示例#1
0
    $ws_worker->server = new \Server\Server();
    $ws_worker->config = json_decode(file_get_contents(__DIR__ . '/config.json'), true);
    $ws_worker->worlds = array();
    foreach (range(0, $ws_worker->config['nb_worlds'] - 1) as $i) {
        $world = new WorldServer('world' . ($i + 1), $ws_worker->config['nb_players_per_world'], $ws_worker);
        $world->run($ws_worker->config['map_filepath']);
        $ws_worker->worlds[] = $world;
    }
};
$ws_worker->onConnect = function ($connection) use($ws_worker) {
    $connection->server = $ws_worker->server;
    if (isset($server->connectionCallback)) {
        call_user_func($ws_worker->server->connectionCallback);
    }
    $world = Utils::detect($ws_worker->worlds, function ($world) use($ws_worker) {
        return $world->playerCount < $ws_worker->config['nb_players_per_world'];
    });
    $world->updatePopulation(null);
    if ($world && isset($world->connectCallback)) {
        call_user_func($world->connectCallback, new Player($connection, $world));
    }
};
// 这里使用workerman的WebServer运行Web目录。Web目录也可以用nginx/Apache等容器运行
$web = new WebServer("http://0.0.0.0:8787");
$web->count = 6;
$web->name = 'BrowserQuestWeb';
$web->addRoot('www.your_domain.com', __DIR__ . '/Web');
// 如果不是在根目录启动,则运行runAll方法
if (!defined('GLOBAL_START')) {
    Worker::runAll();
}
 public function removeFromGroups($entity)
 {
     $self = $this;
     $oldGroups = array();
     if ($entity && isset($entity->group)) {
         $group = $this->groups[$entity->group];
         if ($entity instanceof Player) {
             $group->players = Utils::reject($group->players, function ($id) use($entity) {
                 return $id == $entity->id;
             });
         }
         $this->map->forEachAdjacentGroup($entity->group, function ($id) use($entity, &$oldGroups, $self) {
             if (isset($self->groups[$id]->entities[$entity->id])) {
                 unset($self->groups[$id]->entities[$entity->id]);
                 $oldGroups[] = $id;
             }
         });
         $entity->group = null;
     }
     return $oldGroups;
 }
示例#3
0
 public function onClientMessage($connection, $data)
 {
     $message = json_decode($data, true);
     $action = $message[0];
     if (!$this->hasEnteredGame && $action !== TYPES_MESSAGES_HELLO) {
         $this->connection->close("Invalid handshake message: " . $data);
         return;
     }
     $this->resetTimeout();
     if ($action === TYPES_MESSAGES_HELLO) {
         $name = $message[1];
         $this->name = $name === "" ? "lorem ipsum" : $name;
         $this->kind = TYPES_ENTITIES_WARRIOR;
         $this->equipArmor($message[2]);
         $this->equipWeapon($message[3]);
         $this->orientation = Utils::randomOrientation();
         $this->updateHitPoints();
         $this->updatePosition();
         $this->server->addPlayer($this);
         call_user_func($this->server->enterCallback, $this);
         $this->connection->send(json_encode(array(TYPES_MESSAGES_WELCOME, $this->id, $this->name, $this->x, $this->y, $this->hitPoints)));
         $this->hasEnteredGame = true;
         $this->isDead = false;
     } elseif ($action == TYPES_MESSAGES_WHO) {
         array_shift($message);
         $this->server->pushSpawnsToPlayer($this, $message);
     } else {
         if ($action === TYPES_MESSAGES_ZONE) {
             call_user_func($this->zoneCallback);
         } else {
             if ($action == TYPES_MESSAGES_CHAT) {
                 $msg = trim($message[1]);
                 // Sanitized messages may become empty. No need to broadcast empty chat messages.
                 if ($msg) {
                     $this->broadcastToZone(new Messages\Chat($this, $msg), false);
                 }
             } else {
                 if ($action == TYPES_MESSAGES_MOVE) {
                     if ($this->moveCallback) {
                         $x = $message[1];
                         $y = $message[2];
                         if ($this->server->isValidPosition($x, $y)) {
                             $this->setPosition($x, $y);
                             $this->clearTarget();
                             $this->broadcast(new Messages\Move($this));
                             call_user_func($this->moveCallback, $this->x, $this->y);
                         }
                     }
                 } else {
                     if ($action == TYPES_MESSAGES_LOOTMOVE) {
                         if ($this->lootmoveCallback) {
                             $this->setPosition($message[1], $message[2]);
                             $item = $this->server->getEntityById($message[3]);
                             if ($item) {
                                 $this->clearTarget();
                                 $this->broadcast(new Messages\LootMove($this, $item));
                                 call_user_func($this->lootmoveCallback, $this->x, $this->y);
                             }
                         }
                     } else {
                         if ($action == TYPES_MESSAGES_AGGRO) {
                             if ($this->moveCallback) {
                                 $this->server->handleMobHate($message[1], $this->id, 5);
                             }
                         } else {
                             if ($action == TYPES_MESSAGES_ATTACK) {
                                 $mob = $this->server->getEntityById($message[1]);
                                 if ($mob) {
                                     $this->setTarget($mob);
                                     $this->server->broadcastAttacker($this);
                                 }
                             } else {
                                 if ($action == TYPES_MESSAGES_HIT) {
                                     $mob = $this->server->getEntityById($message[1]);
                                     if ($mob) {
                                         $dmg = Formulas::dmg($this->weaponLevel, $mob->armorLevel);
                                         if ($dmg > 0 && is_callable(array($mob, 'receiveDamage'))) {
                                             $mob->receiveDamage($dmg, $this->id);
                                             $this->server->handleMobHate($mob->id, $this->id, $dmg);
                                             $this->server->handleHurtEntity($mob, $this, $dmg);
                                         }
                                     }
                                 } else {
                                     if ($action == TYPES_MESSAGES_HURT) {
                                         $mob = $this->server->getEntityById($message[1]);
                                         if ($mob && $this->hitPoints > 0) {
                                             $this->hitPoints -= Formulas::dmg($mob->weaponLevel, $this->armorLevel);
                                             $this->server->handleHurtEntity($this);
                                             if ($this->hitPoints <= 0) {
                                                 $this->isDead = true;
                                                 if (!empty($this->firepotionTimeout)) {
                                                     Timer::del($this->firepotionTimeout);
                                                     $this->firepotionTimeout = 0;
                                                 }
                                             }
                                         }
                                     } else {
                                         if ($action == TYPES_MESSAGES_LOOT) {
                                             $item = $this->server->getEntityById($message[1]);
                                             if ($item) {
                                                 $kind = $item->kind;
                                                 if (Types::isItem($kind)) {
                                                     $this->broadcast($item->despawn());
                                                     $this->server->removeEntity($item);
                                                     if ($kind == TYPES_ENTITIES_FIREPOTION) {
                                                         $this->updateHitPoints();
                                                         $this->broadcast($this->equip(TYPES_ENTITIES_FIREFOX));
                                                         $this->firepotionTimeout = Timer::add(15, array($this, 'firepotionTimeoutCallback'), array(), false);
                                                         $hitpoints = new Messages\HitPoints($this->maxHitPoints);
                                                         $data = $hitpoints->serialize();
                                                         $this->connection->send(json_encode($data));
                                                     } else {
                                                         if (Types::isHealingItem($kind)) {
                                                             $amount = 0;
                                                             switch ($kind) {
                                                                 case TYPES_ENTITIES_FLASK:
                                                                     $amount = 40;
                                                                     break;
                                                                 case TYPES_ENTITIES_BURGER:
                                                                     $amount = 100;
                                                                     break;
                                                             }
                                                             if (!$this->hasFullHealth()) {
                                                                 $this->regenHealthBy($amount);
                                                                 $this->server->pushToPlayer($this, $this->health());
                                                             }
                                                         } else {
                                                             if (Types::isArmor($kind) || Types::isWeapon($kind)) {
                                                                 $this->equipItem($item);
                                                                 $this->broadcast($this->equip($kind));
                                                             }
                                                         }
                                                     }
                                                 }
                                             }
                                         } else {
                                             if ($action == TYPES_MESSAGES_TELEPORT) {
                                                 $x = $message[1];
                                                 $y = $message[2];
                                                 if ($this->server->isValidPosition($x, $y)) {
                                                     $this->setPosition($x, $y);
                                                     $this->clearTarget();
                                                     $this->broadcast(new Messages\Teleport($this));
                                                     $this->server->handlePlayerVanish($this);
                                                     $this->server->pushRelevantEntityListTo($this);
                                                 }
                                             } else {
                                                 if ($action == TYPES_MESSAGES_OPEN) {
                                                     $chest = $this->server->getEntityById($message[1]);
                                                     if ($chest && $chest instanceof Chest) {
                                                         $this->server->handleOpenedChest($chest, $this);
                                                     }
                                                 } else {
                                                     if ($action == TYPES_MESSAGES_CHECK) {
                                                         $checkpoint = $this->server->map->getCheckpoint($message[1]);
                                                         if ($checkpoint) {
                                                             $this->lastCheckpoint = $checkpoint;
                                                         }
                                                     } else {
                                                         if (isset($this->messageCallback)) {
                                                             call_user_func($this->messageCallback, $message);
                                                         }
                                                     }
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
         }
     }
 }
示例#4
0
 public function distanceToSpawningPoint($x, $y)
 {
     return Utils::distanceTo($x, $y, $this->spawningX, $this->spawningY);
 }
示例#5
0
 public function serialize()
 {
     return array(TYPES_MESSAGES_DROP, $this->mob->id, $this->item->id, $this->item->kind, Utils::pluck($this->mob->hatelist, 'id'));
 }