public void ViewVisibleThread() { Output.WriteLine("[WORLD SERVER]View Visible Thread started"); while (true) { ArrayList deadPlayers = new ArrayList(); ArrayList removeEntities = new ArrayList(); // Clean lock (WorldSocket.Clients.SyncRoot) { foreach (string clientKey in WorldSocket.Clients.Keys) { // Collect dead players to arraylist WorldClient thisclient = WorldSocket.Clients[clientKey] as WorldClient; if (thisclient.Alive == false) { // Add dead Player to the List - we need later to clear them deadPlayers.Add(clientKey); } } cleanDeadPlayers(deadPlayers); } // Check for Player Views lock (WorldSocket.Clients.SyncRoot) { foreach (string clientKey in WorldSocket.Clients.Keys) { // get Current client WorldClient currentClient = WorldSocket.Clients[clientKey] as WorldClient; // Loop all Clients and check if we need to create a view for it foreach (string clientOtherKey in WorldSocket.Clients.Keys) { WorldClient otherClient = WorldSocket.Clients[clientOtherKey] as WorldClient; if (otherClient != currentClient) { ClientView clientView = currentClient.viewMan.getViewForEntityAndGo(otherClient.playerData.getEntityId(), NumericalUtils.ByteArrayToUint16(otherClient.playerInstance.GetGoid(), 1)); // Create Maths math = new Maths(); double currentPlayerX = 0; double currentPlayerY = 0; double currentPlayerZ = 0; double otherPlayerX = 0; double otherPlayerY = 0; double otherPlayerZ = 0; NumericalUtils.LtVector3dToDoubles(currentClient.playerInstance.Position.getValue(), ref currentPlayerX, ref currentPlayerY, ref currentPlayerZ); NumericalUtils.LtVector3dToDoubles(currentClient.playerInstance.Position.getValue(), ref otherPlayerX, ref otherPlayerY, ref otherPlayerZ); Maths mathUtils = new Maths(); bool playerIsInCircle = mathUtils.IsInCircle((float)currentPlayerX, (float)currentPlayerZ, (float)otherPlayerX, (float)otherPlayerZ, 5000); if (clientView.viewCreated == false && currentClient.playerData.getDistrictId() == otherClient.playerData.getDistrictId() && otherClient.playerData.getOnWorld() && currentClient.playerData.getOnWorld() && playerIsInCircle) { // Spawn player ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(currentClient, "Player " + otherClient.playerInstance.GetName() + " with new View ID " + clientView.ViewID + " jacked in", "BROADCAST"); pak.sendPlayerSpawn(currentClient, otherClient, clientView.ViewID); clientView.spawnId = currentClient.playerData.spawnViewUpdateCounter; clientView.viewCreated = true; } if (clientView.viewCreated && !playerIsInCircle) { // ToDo: delete mob ServerPackets packets = new ServerPackets(); packets.sendSystemChatMessage(currentClient, "Player " + otherClient.playerInstance.GetName() + " with View ID " + clientView.ViewID + " jacked out!", "MODAL"); packets.sendDeleteViewPacket(currentClient, clientView.ViewID); currentClient.viewMan.removeViewByViewId(clientView.ViewID); } } } } } // Spawn/Update for mobs int npcCount = WorldSocket.npcs.Count; for (int i = 0; i < npcCount; i++) { npc thismob = (npc)WorldSocket.npcs[i]; lock (WorldSocket.Clients.SyncRoot) { foreach (string clientKey in WorldSocket.Clients.Keys) { // Loop through all clients WorldClient thisclient = WorldSocket.Clients[clientKey] as WorldClient; if (thisclient.Alive == true) { // Check if if (thisclient.playerData.getOnWorld() == true && thisclient.playerData.waitForRPCShutDown == false) { Maths math = new Maths(); double playerX = 0; double playerY = 0; double playerZ = 0; NumericalUtils.LtVector3dToDoubles(thisclient.playerInstance.Position.getValue(), ref playerX, ref playerY, ref playerZ); Maths mathUtils = new Maths(); bool mobIsInCircle = mathUtils.IsInCircle((float)playerX, (float)playerZ, (float)thismob.getXPos(), (float)thismob.getZPos(), 5000); // ToDo: Check if mob is in circle of player (radian some value that is in a middle range for example 300m) // Create ClientView mobView = thisclient.viewMan.getViewForEntityAndGo(thismob.getEntityId(), NumericalUtils.ByteArrayToUint16(thismob.getGoId(), 1)); if (mobView.viewCreated == false && thismob.getDistrict() == thisclient.playerData.getDistrictId() && thisclient.playerData.getOnWorld() && mobIsInCircle) { ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(thisclient, "Mob with Name " + thismob.getName() + " with new View ID " + mobView.ViewID + " spawned", "BROADCAST"); ServerPackets mobPak = new ServerPackets(); mobPak.spawnMobView(thisclient, thismob, mobView); mobView.spawnId = thisclient.playerData.spawnViewUpdateCounter; mobView.viewCreated = true; } // Update Mob if (mobView.viewCreated == true && thismob.getDistrict() == thisclient.playerData.getDistrictId() && thisclient.playerData.getOnWorld()) { // ToDo: We need to involve the Statuslist here and we need to move them finaly if (thismob.getIsDead() == false) { updateMob(thisclient, ref thismob, mobView); } } // Mob moves outside - should delete it if (mobView.viewCreated == true && !mobIsInCircle && thismob.getDistrict() == thisclient.playerData.getDistrictId()) { // ToDo: delete mob ServerPackets packets = new ServerPackets(); packets.sendDeleteViewPacket(thisclient, mobView.ViewID); packets.sendSystemChatMessage(thisclient, "MobView (" + thismob.getName() + " LVL: " + thismob.getLevel() + " ) with View ID " + mobView.ViewID + " is out of range and is deleted!", "MODAL"); thisclient.viewMan.removeViewByViewId(mobView.ViewID); } } } } } thismob.updateClient = false; } Thread.Sleep(500); } }
/** * This handles all RPC requests for the client */ public void HandleRpc(int header, ref byte[] rpcData) { ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(Store.currentClient, "Handle RPC Client Request Header " + StringUtils.bytesToString_NS(NumericalUtils.int32ToByteArray(header, 0)), "BROADCAST"); switch (header) { case (int)RPCRequestHeader.CLIENT_SPAWN_READY: new PlayerHandler().processSpawn(); new PlayerHandler().processAttributes(); break; case (int)RPCRequestHeader.CLIENT_CLOSE_COMBAT: Output.WriteRpcLog("CLOSE COMBAT REQUEST"); new TestUnitHandler().testCloseCombat(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_LEAVE_COMBAT: break; case (int)RPCRequestHeader.CLIENT_RANGE_COMBAT: Output.WriteRpcLog("RANGE COMBAT REQUEST"); new TestUnitHandler().testCloseCombat(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_CHAT: new ChatHandler().processChat(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_OBJECTINTERACTION_DYNAMIC: new ObjectInteractionHandler().processObjectDynamic(ref rpcData); Output.writeToLogForConsole("RPCMAIN : Handle OBJECTINTERACTION_DYNAMIC"); break; case (int)RPCRequestHeader.CLIENT_OBJECTINTERACTION_STATIC: new ObjectInteractionHandler().processObjectStatic(ref rpcData); Output.writeToLogForConsole("RPCMAIN : Handle OBJECTINTERACTION_STATIC"); break; case (int)RPCRequestHeader.CLIENT_JUMP: Output.writeToLogForConsole("RPCMAIN : Handle JUMP"); //ToDo: Split Jump and Hyperjump //new TestUnitHandler().processHyperJump(ref rpcData); new TestUnitHandler().processHyperJump(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_TARGET: new PlayerHelper().processTargetChange(ref rpcData, Store.currentClient); break; case (int)RPCRequestHeader.CLIENT_MISSION_REQUEST: new MissionHandler().processMissionList(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_MISSION_INFO: new MissionHandler().processLoadMissionInfo(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_MISSION_ACCEPT: new MissionHandler().processMissionaccept(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_MISSION_ABORT: new MissionHandler().processAbortMission(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_PARTY_LEAVE: break; // Team case (int)RPCRequestHeader.CLIENT_HANDLE_MISSION_INVITE: new TeamHandler().processTeamInviteAnswer(ref rpcData); break; // Faction and Crews case (int)RPCRequestHeader.CLIENT_FACTION_INFO: new FCHandler().processLoadFactionName(ref rpcData); // ToDo: implement response with following format : // size + 80 f5 + uint32 factionId + String(40 size? unusual...) // Example: 30 80 f5 11 ba 00 00 48 79 50 6e 30 74 69 5a 65 44 20 4d 69 4e 64 5a 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 break; // Abilitys case (int)RPCRequestHeader.CLIENT_UPGRADE_ABILITY_LEVEL: // ToDo: Research and implement^^ break; case (int)RPCRequestHeader.CLIENT_ABILITY_HANDLER: new AbilityHandler().processAbility(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_CHANGE_CT: new PlayerHelper().processUpdateExp(); break; case (int)RPCRequestHeader.CLIENT_ABILITY_LOADER: new PlayerHelper().processLoadAbility(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_HARDLINE_EXIT_LA_CONFIRM: new TeleportHandler().processHardlineExitConfirm(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_READY_WORLDCHANGE: Output.WriteLine("RPCMAIN : RESET_RPC detect"); new TeleportHandler().processTeleportReset(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_TELEPORT_HL: new TeleportHandler().processHardlineTeleport(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_HARDLINE_STATUS_REQUEST: new TeleportHandler().processHardlineStatusRequest(ref rpcData); break; // Inventory case (int)RPCRequestHeader.CLIENT_ITEM_MOVE_SLOT: new InventoryHandler().processItemMove(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_ITEM_RECYCLE: new InventoryHandler().processItemDelete(ref rpcData); break; // Vendor case (int)RPCRequestHeader.CLIENT_VENDOR_BUY: new VendorHandler().processBuyItem(ref rpcData); break; // MarketPlace case (int)RPCRequestHeader.CLIENT_MP_OPEN: new TestUnitHandler().processMarketTest(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_MP_LIST_ITEMS: new MarketPlaceHandler().processMarketplaceList(ref rpcData); break; // Command Helper case (int)RPCRequestHeader.CLIENT_CMD_WHEREAMI: new CommandHandler().processWhereamiCommand(ref rpcData); break; // Emote and Mood Helpers case (int)RPCRequestHeader.CLIENT_CHANGE_MOOD: new PlayerHandler().processMood(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_EMOTE: new PlayerHandler().processEmote(ref rpcData); break; case (int)RPCRequestHeader.CLIENT_REGION_LOADED: new RegionHandler().processRegionLoaded(ref rpcData); //new PlayerInitHelper().processRegionSettings(); break; default: //PASS :D byte[] headers = NumericalUtils.int32ToByteArray(header, 1); string message = "RPCMAIN : Unknown Header " + StringUtils.bytesToString_NS(new byte[] { headers[0], headers[1] }) + " \n Content:\n " + StringUtils.bytesToString_NS(rpcData); Output.WriteLine(message); Output.WriteRpcLog(message); break; } }