void ofxKinect::findPlayer(){ XnUserID aUsers[20]; XnUInt16 nUsers = 20; userGenerator.GetUsers(aUsers, nUsers); for (int i = 0; i < nUsers; ++i) { if (AssignPlayer(aUsers[i])) return; } }
void FindPlayer() { if (g_nPlayer != 0) { return; } XnUserID aUsers[20]; XnUInt16 nUsers = 20; g_UserGenerator.GetUsers(aUsers, nUsers); for (int i = 0; i < nUsers; ++i) { if (AssignPlayer(aUsers[i])) return; } }
void XN_CALLBACK_TYPE NewUser(xn::UserGenerator& generator, XnUserID user, void* pCookie) { if (!g_bCalibrated) // check on player0 is enough { printf("Look for pose\n"); g_UserGenerator.GetPoseDetectionCap().StartPoseDetection("Psi", user); return; } AssignPlayer(user); // if (g_nPlayer == 0) // { // printf("Assigned user\n"); // g_UserGenerator.GetSkeletonCap().LoadCalibrationData(user, 0); // g_UserGenerator.GetSkeletonCap().StartTracking(user); // g_nPlayer = user; // } }
// Update void _Bot::Update(double FrameTime) { // Update network Network->Update(FrameTime); // Get events _NetworkEvent NetworkEvent; while(Network->GetNetworkEvent(NetworkEvent)) { switch(NetworkEvent.Type) { case _NetworkEvent::CONNECT: { std::cout << Username << " connected" << std::endl; _Buffer Packet; Packet.Write<PacketType>(PacketType::ACCOUNT_LOGININFO); Packet.WriteBit(0); Packet.WriteString(Username.c_str()); Packet.WriteString(Password.c_str()); Packet.Write<uint64_t>(0); Network->SendPacket(Packet); } break; case _NetworkEvent::DISCONNECT: std::cout << Username << " disconnected" << std::endl; ObjectManager->Clear(); AssignPlayer(nullptr); delete Battle; delete Map; Battle = nullptr; Map = nullptr; break; case _NetworkEvent::PACKET: HandlePacket(*NetworkEvent.Data); delete NetworkEvent.Data; break; } } if(!Player || !Map) return; // Update goals EvaluateGoal(); // Set input if(Player->AcceptingMoveInput()) { int InputState = GetNextInputState(); Player->InputStates.clear(); if(InputState) Player->InputStates.push_back(InputState); } // Update objects ObjectManager->Update(FrameTime); // Update map Map->Update(FrameTime); // Send input to server if(Player->Moved) { if(Path.size()) Path.erase(Path.begin()); _Buffer Packet; Packet.Write<PacketType>(PacketType::WORLD_MOVECOMMAND); Packet.Write<char>((char)Player->Moved); Network->SendPacket(Packet); } // Update battle system if(Battle) { if(!Player->PotentialAction.IsSet()) { Battle->ClientHandleInput(_Actions::SKILL1); Battle->ClientHandleInput(_Actions::SKILL1); } if(!Player->Battle) { delete Battle; Battle = nullptr; } else Battle->Update(FrameTime); } }
// Handle packet void _Bot::HandlePacket(_Buffer &Data) { PacketType Type = Data.Read<PacketType>(); //std::cout << (int)Type << std::endl; switch(Type) { case PacketType::ACCOUNT_SUCCESS: { // Request character list _Buffer Packet; Packet.Write<PacketType>(PacketType::CHARACTERS_REQUEST); Network->SendPacket(Packet); } break; case PacketType::ACCOUNT_NOTFOUND: { _Buffer Packet; Packet.Write<PacketType>(PacketType::ACCOUNT_LOGININFO); Packet.WriteBit(1); Packet.WriteString(Username.c_str()); Packet.WriteString(Password.c_str()); Packet.Write<uint64_t>(0); Network->SendPacket(Packet); } break; case PacketType::CHARACTERS_LIST: { // Get count uint8_t CharacterCount = Data.Read<uint8_t>(); std::cout << "character count: " << (int)CharacterCount << std::endl; // Get characters int FirstSlot = -1; for(size_t i = 0; i < CharacterCount; i++) { size_t Slot = Data.Read<uint8_t>(); Data.ReadString(); Data.Read<uint32_t>(); Data.Read<int32_t>(); if(FirstSlot == -1) FirstSlot = (int)Slot; } // Create character if(FirstSlot == -1) { std::string Name = Username + "_" + std::to_string(GetRandomInt(0, 1000)); _Buffer Packet; Packet.Write<PacketType>(PacketType::CREATECHARACTER_INFO); Packet.WriteString(Name.c_str()); Packet.Write<uint32_t>(1); Packet.Write<uint32_t>(1); Packet.Write<uint8_t>(0); Network->SendPacket(Packet); FirstSlot = 0; } _Buffer Packet; Packet.Write<PacketType>(PacketType::CHARACTERS_PLAY); Packet.Write<uint8_t>((uint8_t)FirstSlot); Network->SendPacket(Packet); } break; case PacketType::OBJECT_STATS: if(Player) Player->UnserializeStats(Data); break; case PacketType::WORLD_CHANGEMAPS: { // Load map NetworkIDType MapID = (NetworkIDType)Data.Read<uint32_t>(); double Clock = Data.Read<double>(); if(Player) std::cout << Player->NetworkID << " "; std::cout << "WORLD_CHANGEMAPS " << MapID << std::endl; // Delete old map and create new if(!Map || Map->NetworkID != MapID) { if(Map) { delete Pather; delete Map; Pather = nullptr; Map = nullptr; } Map = new _Map(); Map->Clock = Clock; Map->NetworkID = MapID; Map->Load(Stats->GetMap(MapID)->File); AssignPlayer(nullptr); Pather = new micropather::MicroPather(Map, (unsigned)(Map->Size.x * Map->Size.y), 4); Path.clear(); } } break; case PacketType::WORLD_OBJECTLIST: { ObjectManager->Clear(); AssignPlayer(nullptr); // Read header NetworkIDType ClientNetworkID = Data.Read<NetworkIDType>(); NetworkIDType ObjectCount = Data.Read<NetworkIDType>(); // Create objects //std::cout << ClientNetworkID << " WORLD_OBJECTLIST count=" << ObjectCount << std::endl; for(NetworkIDType i = 0; i < ObjectCount; i++) { NetworkIDType NetworkID = Data.Read<NetworkIDType>(); // Create object _Object *Object = CreateObject(Data, NetworkID); // Set player pointer if(Object->NetworkID == ClientNetworkID) AssignPlayer(Object); else Object->CalcLevelStats = false; } if(Player) { } else { // Error } } break; case PacketType::WORLD_CREATEOBJECT: { if(!Map || !Player) break; // Read packet NetworkIDType NetworkID = Data.Read<NetworkIDType>(); //std::cout << Player->NetworkID << " WORLD_CREATEOBJECT NetworkID=" << NetworkID << std::endl; // Check id if(NetworkID != Player->NetworkID) { // Create object CreateObject(Data, NetworkID); } } break; case PacketType::WORLD_DELETEOBJECT: { NetworkIDType NetworkID = Data.Read<NetworkIDType>(); // Get object _Object *Object = ObjectManager->GetObject(NetworkID); if(Object && Object != Player) { Object->Deleted = true; } } break; case PacketType::WORLD_OBJECTUPDATES: //HandleObjectUpdates(Data); break; case PacketType::WORLD_POSITION: { if(!Player) break; Player->Position = Data.Read<glm::ivec2>(); Player->WaitForServer = false; Player->TeleportTime = -1; } break; case PacketType::WORLD_TELEPORTSTART: Player->TeleportTime = Data.Read<double>(); break; case PacketType::EVENT_START: //HandleEventStart(Data); break; case PacketType::CHAT_MESSAGE: //HandleChatMessage(Data); break; case PacketType::INVENTORY: //HandleInventory(Data); break; case PacketType::INVENTORY_USE: //HandleInventoryUse(Data); break; case PacketType::INVENTORY_SWAP: //HandleInventorySwap(Data); break; case PacketType::INVENTORY_UPDATE: //HandleInventoryUpdate(Data); break; case PacketType::INVENTORY_GOLD: //HandleInventoryGold(Data); break; case PacketType::TRADE_REQUEST: //HandleTradeRequest(Data); break; case PacketType::TRADE_CANCEL: //HandleTradeCancel(Data); break; case PacketType::TRADE_ITEM: //HandleTradeItem(Data); break; case PacketType::TRADE_GOLD: //HandleTradeGold(Data); break; case PacketType::TRADE_ACCEPT: //HandleTradeAccept(Data); break; case PacketType::TRADE_EXCHANGE: //HandleTradeExchange(Data); break; case PacketType::BATTLE_START: { std::cout << "BATTLE_START" << std::endl; // Already in a battle if(Battle) break; // Allow player to hit menu buttons Player->WaitForServer = false; // Create a new battle instance Battle = new _Battle(); Battle->Manager = ObjectManager; Battle->Stats = Stats; Battle->Scripting = Scripting; Battle->ClientPlayer = Player; Battle->ClientNetwork = Network.get(); Battle->Unserialize(Data, nullptr); } break; case PacketType::BATTLE_ACTION: //HandleBattleAction(Data); break; case PacketType::BATTLE_LEAVE: { NetworkIDType NetworkID = Data.Read<NetworkIDType>(); _Object *Object = ObjectManager->GetObject(NetworkID); if(Object) Battle->RemoveFighter(Object); } break; case PacketType::BATTLE_END: { if(!Player || !Battle) return; std::cout << "BATTLE_END" << std::endl; Player->WaitForServer = false; _StatChange StatChange; StatChange.Object = Player; // Get ending stats bool SideDead[2]; SideDead[0] = Data.ReadBit(); SideDead[1] = Data.ReadBit(); int PlayerKills = Data.Read<uint8_t>(); int MonsterKills = Data.Read<uint8_t>(); StatChange.Values[StatType::EXPERIENCE].Integer = Data.Read<int32_t>(); StatChange.Values[StatType::GOLD].Integer = Data.Read<int32_t>(); uint8_t ItemCount = Data.Read<uint8_t>(); for(uint8_t i = 0; i < ItemCount; i++) { uint32_t ItemID = Data.Read<uint32_t>(); const _Item *Item = Stats->Items[ItemID]; int Count = (int)Data.Read<uint8_t>(); // Add items Player->Inventory->AddItem(Item, Count); } // Check win or death int PlayerSide = Player->BattleSide; int OtherSide = !PlayerSide; if(!SideDead[PlayerSide] && SideDead[OtherSide]) { Player->PlayerKills += PlayerKills; Player->MonsterKills += MonsterKills; } Player->Battle = nullptr; delete Battle; Battle = nullptr; DetermineNextGoal(); } break; case PacketType::ACTION_RESULTS: { // Create result _ActionResult ActionResult; bool DecrementItem = Data.ReadBit(); bool SkillUnlocked = Data.ReadBit(); bool ItemUnlocked = Data.ReadBit(); uint32_t ItemID = Data.Read<uint32_t>(); int InventorySlot = (int)Data.Read<char>(); ActionResult.ActionUsed.Item = Stats->Items[ItemID]; // Set texture if(ActionResult.ActionUsed.Item) ActionResult.Texture = ActionResult.ActionUsed.Item->Texture; // Get source change HandleStatChange(Data, ActionResult.Source); // Update source fighter if(ActionResult.Source.Object) { ActionResult.Source.Object->TurnTimer = 0.0; ActionResult.Source.Object->Action.Unset(); ActionResult.Source.Object->Targets.clear(); // Use item on client if(Player == ActionResult.Source.Object) { if(ActionResult.ActionUsed.Item) { if(DecrementItem) { size_t Index; if(Player->Inventory->FindItem(ActionResult.ActionUsed.Item, Index, (size_t)InventorySlot)) { Player->Inventory->DecrementItemCount(Index, -1); Player->RefreshActionBarCount(); } } if(SkillUnlocked) { Player->Skills[ActionResult.ActionUsed.Item->ID] = 0; } if(ItemUnlocked) { Player->Unlocks[ActionResult.ActionUsed.Item->UnlockID].Level = 1; } } } } // Update targets uint8_t TargetCount = Data.Read<uint8_t>(); for(uint8_t i = 0; i < TargetCount; i++) { HandleStatChange(Data, ActionResult.Source); HandleStatChange(Data, ActionResult.Target); if(Battle) { // No damage dealt if((ActionResult.ActionUsed.GetTargetType() == TargetType::ENEMY || ActionResult.ActionUsed.GetTargetType() == TargetType::ENEMY_ALL) && ((ActionResult.Target.HasStat(StatType::HEALTH) && ActionResult.Target.Values[StatType::HEALTH].Float == 0.0f) || ActionResult.Target.HasStat(StatType::MISS))) { ActionResult.Timeout = HUD_ACTIONRESULT_TIMEOUT_SHORT; ActionResult.Speed = HUD_ACTIONRESULT_SPEED_SHORT; } else { ActionResult.Timeout = HUD_ACTIONRESULT_TIMEOUT; ActionResult.Speed = HUD_ACTIONRESULT_SPEED; } Battle->ActionResults.push_back(ActionResult); } else if(ActionResult.Target.Object == Player) { } } } break; case PacketType::STAT_CHANGE: { _StatChange StatChange; HandleStatChange(Data, StatChange); } break; case PacketType::WORLD_HUD: Player->Health = Data.Read<float>(); Player->Mana = Data.Read<float>(); Player->MaxHealth = Data.Read<float>(); Player->MaxMana = Data.Read<float>(); Player->Experience = Data.Read<int32_t>(); Player->Gold = Data.Read<int32_t>(); Player->CalculateStats(); break; default: break; } }
bool CNetServerWorker::RunStep() { // Check for messages from the game thread. // (Do as little work as possible while the mutex is held open, // to avoid performance problems and deadlocks.) m_ScriptInterface->GetRuntime()->MaybeIncrementalGC(0.5f); JSContext* cx = m_ScriptInterface->GetContext(); JSAutoRequest rq(cx); std::vector<std::pair<int, CStr> > newAssignPlayer; std::vector<bool> newStartGame; std::vector<std::pair<CStr, int> > newPlayerReady; std::vector<bool> newPlayerResetReady; std::vector<std::string> newGameAttributes; std::vector<u32> newTurnLength; { CScopeLock lock(m_WorkerMutex); if (m_Shutdown) return false; newStartGame.swap(m_StartGameQueue); newPlayerReady.swap(m_PlayerReadyQueue); newPlayerResetReady.swap(m_PlayerResetReadyQueue); newAssignPlayer.swap(m_AssignPlayerQueue); newGameAttributes.swap(m_GameAttributesQueue); newTurnLength.swap(m_TurnLengthQueue); } for (size_t i = 0; i < newAssignPlayer.size(); ++i) AssignPlayer(newAssignPlayer[i].first, newAssignPlayer[i].second); for (size_t i = 0; i < newPlayerReady.size(); ++i) SetPlayerReady(newPlayerReady[i].first, newPlayerReady[i].second); if (!newPlayerResetReady.empty()) ClearAllPlayerReady(); if (!newGameAttributes.empty()) { JS::RootedValue gameAttributesVal(cx); GetScriptInterface().ParseJSON(newGameAttributes.back(), &gameAttributesVal); UpdateGameAttributes(&gameAttributesVal); } if (!newTurnLength.empty()) SetTurnLength(newTurnLength.back()); // Do StartGame last, so we have the most up-to-date game attributes when we start if (!newStartGame.empty()) StartGame(); // Perform file transfers for (size_t i = 0; i < m_Sessions.size(); ++i) m_Sessions[i]->GetFileTransferer().Poll(); // Process network events: ENetEvent event; int status = enet_host_service(m_Host, &event, HOST_SERVICE_TIMEOUT); if (status < 0) { LOGERROR("CNetServerWorker: enet_host_service failed (%d)", status); // TODO: notify game that the server has shut down return false; } if (status == 0) { // Reached timeout with no events - try again return true; } // Process the event: switch (event.type) { case ENET_EVENT_TYPE_CONNECT: { // Report the client address char hostname[256] = "(error)"; enet_address_get_host_ip(&event.peer->address, hostname, ARRAY_SIZE(hostname)); LOGMESSAGE("Net server: Received connection from %s:%u", hostname, (unsigned int)event.peer->address.port); // Set up a session object for this peer CNetServerSession* session = new CNetServerSession(*this, event.peer); m_Sessions.push_back(session); SetupSession(session); ENSURE(event.peer->data == NULL); event.peer->data = session; HandleConnect(session); break; } case ENET_EVENT_TYPE_DISCONNECT: { // If there is an active session with this peer, then reset and delete it CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data); if (session) { LOGMESSAGE("Net server: Disconnected %s", DebugName(session).c_str()); // Remove the session first, so we won't send player-update messages to it // when updating the FSM m_Sessions.erase(remove(m_Sessions.begin(), m_Sessions.end(), session), m_Sessions.end()); session->Update((uint)NMT_CONNECTION_LOST, NULL); delete session; event.peer->data = NULL; } break; } case ENET_EVENT_TYPE_RECEIVE: { // If there is an active session with this peer, then process the message CNetServerSession* session = static_cast<CNetServerSession*>(event.peer->data); if (session) { // Create message from raw data CNetMessage* msg = CNetMessageFactory::CreateMessage(event.packet->data, event.packet->dataLength, GetScriptInterface()); if (msg) { LOGMESSAGE("Net server: Received message %s of size %lu from %s", msg->ToString().c_str(), (unsigned long)msg->GetSerializedLength(), DebugName(session).c_str()); HandleMessageReceive(msg, session); delete msg; } } // Done using the packet enet_packet_destroy(event.packet); break; } case ENET_EVENT_TYPE_NONE: break; } return true; }
// Update void _Bot::Update(double FrameTime) { // Update network Network->Update(FrameTime); // Get events ae::_NetworkEvent NetworkEvent; while(Network->GetNetworkEvent(NetworkEvent)) { switch(NetworkEvent.Type) { case ae::_NetworkEvent::CONNECT: { //std::cout << Username << " connected" << std::endl; ae::_Buffer Packet; Packet.Write<PacketType>(PacketType::ACCOUNT_LOGININFO); Packet.WriteBit(0); Packet.WriteString(Username.c_str()); Packet.WriteString(Password.c_str()); Packet.Write<uint64_t>(0); Network->SendPacket(Packet); } break; case ae::_NetworkEvent::DISCONNECT: //std::cout << Username << " disconnected" << std::endl; ObjectManager->Clear(); AssignPlayer(nullptr); delete Battle; delete Map; Battle = nullptr; Map = nullptr; break; case ae::_NetworkEvent::PACKET: HandlePacket(*NetworkEvent.Data); delete NetworkEvent.Data; break; } } if(!Player || !Map) return; // Respawn if(!Player->Controller->WaitForServer && !Player->Character->IsAlive()) { ae::_Buffer Packet; Packet.Write<PacketType>(PacketType::WORLD_RESPAWN); Network->SendPacket(Packet); Player->Controller->WaitForServer = true; return; } // Call ai script if(Scripting->StartMethodCall(Script, "Update")) { Scripting->PushReal(FrameTime); Scripting->PushObject(Player); Scripting->MethodCall(2, 0); Scripting->FinishMethodCall(); } // Set input if(Player->Character->AcceptingMoveInput()) { int InputState = 0; // Call ai input script if(Scripting->StartMethodCall(Script, "GetInputState")) { Scripting->PushObject(Player); Scripting->MethodCall(1, 1); InputState = Scripting->GetInt(1); Scripting->FinishMethodCall(); } Player->Controller->InputStates.clear(); if(InputState) Player->Controller->InputStates.push_back(InputState); } // Update objects ObjectManager->Update(FrameTime); // Update map Map->Update(FrameTime); // Send input to server if(Player->Controller->DirectionMoved) { if(Player->Character->Path.size()) Player->Character->Path.erase(Player->Character->Path.begin()); ae::_Buffer Packet; Packet.Write<PacketType>(PacketType::WORLD_MOVECOMMAND); Packet.Write<char>((char)Player->Controller->DirectionMoved); Network->SendPacket(Packet); } // Update battle system if(Battle) { if(!Player->Fighter->PotentialAction.IsSet()) { Battle->ClientHandleInput(Action::GAME_SKILL1); Battle->ClientHandleInput(Action::GAME_SKILL1); } if(!Player->Character->Battle) { delete Battle; Battle = nullptr; } else Battle->Update(FrameTime); } }