public ClientView addView(UInt64 entityId, UInt32 goId) { // Add the Object to the client View List currentViewID++; ClientView newView = new ClientView(goId, currentViewID, entityId); views.Add(newView); return newView; }
/// <summary> /// This sends a View Create/Update/Delete Packet to all Players /// </summary> /// <param name="data">Packet Stream without ViewID</param> /// <param name="charId">from charId</param> /// <param name="goId">from GoId</param> public void sendViewPacketToAllPlayers(byte[] data, UInt32 charId, UInt32 goId, UInt64 entityId) { // Send a global message to all connected Players (like shut down Server announce or something) lock (Clients.SyncRoot) { foreach (string clientKey in Clients.Keys) { WorldClient client = Clients[clientKey] as WorldClient; if (client.playerData.getCharID() != charId) { #if DEBUG Output.Write("[ViewThread] Handle View For all Packet for charId : " + charId.ToString()); #endif // Get or generate a View for the GoID ClientView view = client.viewMan.getViewForEntityAndGo(entityId, goId); PacketContent viewPacket = new PacketContent(); if (view.viewCreated == false) { // if view is new , add the viewId at the end (cause its creation) // Remove the 03 01 00 (as it was generate previosly) viewPacket.addByteArray(data); viewPacket.addUint16(view.ViewID, 1); viewPacket.addByte(0x00); } else { // Update View viewPacket.addUint16(view.ViewID, 1); viewPacket.addByteArray(data); viewPacket.addByte(0x00); } if (view.viewNeedsToBeDeleted == true) { // Delete one View viewPacket.addByte(0x01); viewPacket.addByte(0x00); viewPacket.addByte(0x01); // Comand (Delete) viewPacket.addUint16(1, 1); // NumViews to Delete viewPacket.addUint16(view.ViewID, 1); viewPacket.addByte(0x00); } client.messageQueue.addObjectMessage(viewPacket.returnFinalPacket(), false); client.FlushQueue(); } } } }
public void SpawnMobView(WorldClient client, Mob thismob, ClientView mobView) { Output.WriteDebugLog("Spawn MobView Data ( Entity ID : " + thismob.getEntityId() + " Name:" + thismob.getName() + " ID: " + thismob.getMobId() + " RSI HEX: " + thismob.getRsiHex()); Object599 viewData = thismob.getCreationData(); PacketContent pak = new PacketContent(); pak.addUint16(1, 1); pak.addByteArray(Store.world.objMan.GenerateCreationPacket(viewData, 0x0000, client.playerData.assignSpawnIdCounter()).getBytes()); pak.addUint16(mobView.ViewID, 1); pak.addByte(0x00); client.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); client.FlushQueue(); }
public void SendViewUpdateToClientsWhoHasSpawnedView(PacketContent packet, Mob mob) { lock (Clients.SyncRoot) { foreach (string clientKey in Clients.Keys) { WorldClient client = Clients[clientKey] as WorldClient; ClientView mobView = client.viewMan.getViewForEntityAndGo(mob.getEntityId(), NumericalUtils.ByteArrayToUint16(mob.getGoId(), 1)); if (mobView.viewCreated == true && mob.getDistrict() == client.playerData.getDistrictId() && client.playerData.getOnWorld()) { ServerPackets pak = new ServerPackets(); pak.SendNpcUpdateData(mobView.ViewID, client, packet.returnFinalPacket()); } } } }
public void processLootAccepted() { ClientView theMobView = Store.currentClient.viewMan.getViewById(Store.currentClient.playerData.currentSelectedTargetViewId); // ToDo: we currently not know what items and money we should have - we give everytime 5000 currently UInt32 value = 5000; UInt32 newMoneyAmount = (UInt32)Store.currentClient.playerData.getInfo() + value; // Update Info Store.dbManager.WorldDbHandler.SaveInfo(Store.currentClient, newMoneyAmount); Store.currentClient.playerData.setInfo(newMoneyAmount); ServerPackets packet = new ServerPackets(); packet.sendInfoCurrent(Store.currentClient, (UInt32)Store.currentClient.playerData.getInfo()); packet.SendLootAccepted(Store.currentClient); // ToDo: send "loot disabled" }
public void sendSpawnStaticObject(WorldClient client, GameObject creationObjectData, UInt64 entityID) { ClientView staticObjectView = client.viewMan.getViewForEntityAndGo(entityID, NumericalUtils.ByteArrayToUint16(creationObjectData.GetGoid(), 1)); if (staticObjectView.viewCreated == false) { PacketContent pak = new PacketContent(); pak.addUint16(1, 1); pak.addByteArray(Store.world.objMan.GenerateCreationPacket(creationObjectData, 0x0000, client.playerData.assignSpawnIdCounter()).getBytes()); pak.addUint16(staticObjectView.ViewID, 1); pak.addByte(0x00); client.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); client.FlushQueue(); staticObjectView.viewCreated = true; } }
// This method should check if client has a view for a GoID // If not it adds it to his List of Views and response the ClientView Object public ClientView getViewForEntityAndGo(UInt64 entityId, UInt32 goID) { ClientView view = views.Find(delegate(ClientView cv) { return cv.entityId == entityId; }); // Nothing found if (view == null) { view = new ClientView(0, 0, 0); } if (view.ViewID == 0) { view = addView(entityId,goID); } /* else { // The View was already created view.viewCreated = true; }*/ return view; }
// This method should check if client has a view for a GoID // If not it adds it to his List of Views and response the ClientView Object public ClientView getViewForEntityAndGo(UInt64 entityId, UInt32 goID) { ClientView view = views.Find(delegate(ClientView cv) { return(cv.entityId == entityId); }); // Nothing found if (view == null) { view = new ClientView(0, 0, 0); } if (view.ViewID == 0) { view = addView(entityId, goID); } /* * else * { * // The View was already created * view.viewCreated = true; * }*/ return(view); }
public void sendCastAbilityOnEntityId(UInt16 viewId, UInt32 animationId) { ClientView theView = Store.currentClient.viewMan.getViewById(viewId); byte[] updateCount = NumericalUtils.uint16ToByteArrayShort(Store.currentClient.playerData.assignSpawnIdCounter()); Random rand = new Random(); ushort randomHealth = (ushort)rand.Next(3, 1800); // RSI Health FX "send 02 03 02 00 02 80 80 80 90 ed 00 30 22 0a 00 28 06 00 00;" PacketContent pak = new PacketContent(); if (viewId == 0) { viewId = 2; } pak.addUint16(viewId, 1); UInt32 theGoID = 12; if (theView != null) { theGoID = theView.GoID; } switch (theGoID) { case 12: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addByteArray(updateCount); break; case 599: pak.addByte(0x04); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0xc0); pak.addUint16(randomHealth, 1); // health pak.addByte(0xc0); pak.addUint32(animationId, 1); pak.addByteArray(updateCount); pak.addByte(0x05); pak.addByte(0x00); pak.addByte(0x00); string hexNPC = StringUtils.bytesToString(pak.returnFinalPacket()); // Its more a demo - we "one hit" the mob currently so we must update this lock (WorldSocket.npcs.SyncRoot) { for (int i = 0; i < WorldSocket.npcs.Count; i++) { npc thismob = (npc)WorldSocket.npcs[i]; if (thismob.getEntityId() == theView.entityId) { thismob.setIsDead(true); thismob.setIsLootable(true); WorldSocket.npcs[i] = thismob; this.sendNPCDies(theView.ViewID, Store.currentClient, thismob); } } } break; default: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addByteArray(updateCount); break; } string hex = StringUtils.bytesToString(pak.returnFinalPacket()); Store.currentClient.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); Store.currentClient.flushQueue(); }
private static void CheckPlayerMobViews() { // Spawn/Update for mobs int npcCount = WorldSocket.npcs.Count; for (int i = 0; i < npcCount; i++) { Mob thismob = (Mob)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); // Spawn Mob if its in Visibility Range 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) { #if DEBUG ServerPackets pak = new ServerPackets(); pak.sendSystemChatMessage(thisclient, "Mob with Name " + thismob.getName() + " with new View ID " + mobView.ViewID + " spawned", "BROADCAST"); #endif ServerPackets mobPak = new ServerPackets(); mobPak.SpawnMobView(thisclient, thismob, mobView); mobView.spawnId = thisclient.playerData.spawnViewUpdateCounter; mobView.viewCreated = true; thismob.isUpdateable = true; thismob.DoMobUpdate(thismob); } // Delete Mob's View from Client if we are outside if (mobView.viewCreated == true && !mobIsInCircle && thismob.getDistrict() == thisclient.playerData.getDistrictId()) { // ToDo: delete mob ServerPackets packets = new ServerPackets(); packets.sendDeleteViewPacket(thisclient, mobView.ViewID); #if DEBUG packets.sendSystemChatMessage(thisclient, "MobView (" + thismob.getName() + " LVL: " + thismob.getLevel() + " ) with View ID " + mobView.ViewID + " is out of range and is deleted!", "MODAL"); #endif thisclient.viewMan.removeViewByViewId(mobView.ViewID); thismob.isUpdateable = false; } } } } } } }
private static void CheckPlayerViews() { // 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 " + StringUtils.charBytesToString_NZ(otherClient.playerInstance.CharacterName.getValue()) + " 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 " + StringUtils.charBytesToString_NZ(otherClient.playerInstance.CharacterName.getValue()) + " with View ID " + clientView.ViewID + " jacked out!", "MODAL"); packets.sendDeleteViewPacket(currentClient, clientView.ViewID); currentClient.viewMan.removeViewByViewId(clientView.ViewID); } } } } } }
public void sendCastAbilityOnEntityId(UInt16 viewId, UInt32 animationId, UInt16 value) { ClientView theView = Store.currentClient.viewMan.getViewById(viewId); Random randomObject = new Random(); ushort randomHealth = (ushort)randomObject.Next(3, 1800); // RSI Health FX "send 02 03 02 00 02 80 80 80 90 ed 00 30 22 0a 00 28 06 00 00;" PacketContent pak = new PacketContent(); if (viewId == 0) { viewId = 2; } pak.addUint16(viewId, 1); UInt32 theGoID = 12; if (theView != null) { theGoID = theView.GoID; } switch (theGoID) { case 12: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addUintShort(Store.currentClient.playerData.assignSpawnIdCounter()); break; case 599: // Its more a demo - we "one hit" the mob currently so we must update this lock (WorldSocket.npcs.SyncRoot) { for (int i = 0; i < WorldSocket.npcs.Count; i++) { Mob thismob = (Mob)WorldSocket.npcs[i]; if (theView != null && thismob.getEntityId() == theView.entityId) { thismob.HitEnemyWithDamage(value, animationId); if (thismob.getHealthC() <= 0) { thismob.setIsDead(true); this.SendNpcDies(theView.ViewID, Store.currentClient, thismob); // We got some Exp for it - currently we just make a simple trick to calculate some exp // Just take currentLevel * modifier Random rand = new Random(); UInt32 expModifier = (UInt32)rand.Next(100, 500); UInt32 expGained = thismob.getLevel() * expModifier; // Update EXP new PlayerHandler().IncrementPlayerExp(expGained); thismob.setIsLootable(true); } WorldSocket.npcs[i] = thismob; } } } break; default: pak.addByte(0x02); pak.addByte(0x80); pak.addByte(0x80); pak.addByte(0x80); if (viewId == 2) { pak.addByte(0x80); pak.addByte(0xb0); } else { pak.addByte(0x0c); } pak.addUint32(animationId, 1); pak.addUintShort(Store.currentClient.playerData.assignSpawnIdCounter()); break; } string hex = StringUtils.bytesToString(pak.returnFinalPacket()); Store.currentClient.messageQueue.addObjectMessage(pak.returnFinalPacket(), false); Store.currentClient.FlushQueue(); }
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); } }