public static WriteDebugLog ( Object obj ) : void | ||
obj | Object | |
Résultat | void |
public void processRegionLoaded(ref byte[] packet) { PacketReader pakReader = new PacketReader(packet); UInt16 sectorID = pakReader.readUInt16(1); UInt16 objectID = pakReader.readUInt16(1); float xPos = pakReader.readFloat(1); float yPos = pakReader.readFloat(1); float zPos = pakReader.readFloat(1); ServerPackets pak = new ServerPackets(); #if DEBUG pak.sendSystemChatMessage(Store.currentClient, "Region Object ID " + objectID + " in Sector ID" + sectorID + " X:" + xPos + "Y:" + yPos + "Z:" + zPos, "BROADCAST"); Output.WriteDebugLog("Region Object ID " + objectID + " in Sector ID" + sectorID + " X:" + xPos + "Y:" + yPos + "Z:" + zPos); #endif //Store.currentClient.messageQueue.addObjectMessage(StringUtils.hexStringToBytes("020002808080808010110000")); /* * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("80B31100")); * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("3A050011000A0050765053657276657200040002000000")); // PVP Server Setting * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("3A0500170010005076504D6178536166654C6576656C0004000F000000")); // PVP Max Safe Level * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("3A050014000D0057525F52657A4576656E7473002B0048616C6C6F7765656E5F4576656E742C57696E7465723348616C6C6F7765656E466C794579655453454300")); // WR_REZ_events, Halloween, winter etc. * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("3A0500190012004576656E74536C6F74315F456666656374000000")); // Event Slot : 1_Effect * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("3A0500190012004576656E74536C6F74325F456666656374000D00666C796D616E5F69646C653300")); // Event Slot : 2_Effect flyman_idle * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("3A05001B001400466978656442696E6B49444F766572726964650002002000")); // FixedBinkIDOverride * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("8167170020001C2200C60111000000000000002900000807006D786F656D750007006D786F656D750002000200000000000000")); // Holds character name * Store.currentClient.messageQueue.addRpcMessage(StringUtils.hexStringToBytes("80bd051100000000000001")); */ }
public void generateRpcMessageData() { // Example : 04 01 00 15 01 + submessages // Strcut: uint8 04 header + uint8 listcount + uint16 currentRPCCounter + submessageCounter (list1) // If you have 2 lists , the data struct is : uint8 submessagecount + submessages // TODO!!! FINALIZE!! // Here goes code from RPCPacket (As it should be generated on the fly) if (RPCMessages.Count > 0) { content.append((byte)ProtocolHeaders.RPC_PROTOCOL); // ToDo: Figure out what the "Lists" Count should handle ...maybe different types? // Why not having just one List and adding them all ? Maybe a list has a limit ? content.append(0x01); // List Count for RPC Messages Output.WriteLine(" RPC COUNTER BYTES :" + StringUtils.bytesToString(NumericalUtils.uint16ToByteArray(playerData.getRPCCounter(), 0))); content.append(NumericalUtils.uint16ToByteArray(playerData.getRPCCounter(), 0)); content.append(NumericalUtils.uint16ToByteArrayShort((UInt16)RPCMessages.Count)); foreach (SequencedMessage message in RPCMessages) { content.append(message.content); } // Set new RPC Counter UInt16 incrementRpcCounter = playerData.getRPCCounter(); Output.WriteDebugLog("Before RPC Counter :" + incrementRpcCounter.ToString()); incrementRpcCounter += (ushort)RPCMessages.Count; playerData.setRPCCounter(incrementRpcCounter); Output.WriteDebugLog("After RPC Counter :" + incrementRpcCounter.ToString() + " (should added " + RPCMessages.Count.ToString() + ")"); } }
public int generatePathTable() { // We firs test this with just one moove from point x to y // To calc this we need to know the time the object needs to reach this point, // the new point and the rotation to calc pretty to sync client and server position is right // to get a smooth walking :) Maths math = new Maths(); // First choose a new pos in the range LtVector3f newPos = math.RandomPointOnCircle((float)xBase, (float)yBase, (float)zBase, 5.0f * 100); Output.WriteDebugLog("Mob Goes from X: " + this.getXPos() + " , Z: " + this.getZPos() + " to X: " + newPos.a + ", Z: " + newPos.c); double xNew = (double)newPos.a; double zNew = (double)newPos.c; this.destination = newPos; // Try to calculate rotation // Oh this seems to match ...needs more testing later when we fixed random pos double yaw = Math.Atan((double)(xNew - getXPos()) / (zNew - getZPos())) * 128 / Math.PI; double calcRotation = Math.Atan2(Math.Cos(xNew), Math.Sin(zNew) * Math.Sin(zNew)) * 128 / Math.PI; double testRot = Math.Atan2(xNew, zNew) * 180 / Math.PI; double testRot2 = Math.Atan2(xNew, zNew) * 128 / Math.PI; Output.WriteDebugLog("Test Rot with 360 : " + testRot + "| 255 : " + testRot2 + " AND THE YAW: " + yaw + " (Cast to uint16 : " + Convert.ToInt16(yaw) + " )"); int yawVal = (int)Convert.ToInt16(yaw); if (zNew < this.getZPos() || xNew < this.getXPos()) { Output.WriteDebugLog("Need to adjust YAW + 128 from :" + yawVal.ToString() + " to: " + (yawVal + 128).ToString()); yawVal = yawVal + 128; } else { Output.WriteDebugLog("Need to adjust YAW - 128 from :" + yawVal.ToString() + " to: " + (yawVal - 128).ToString()); yawVal = yawVal - 128; } Output.WriteDebugLog("YAW VAL :" + yawVal.ToString()); this.rotation = (ushort)yawVal; Output.WriteDebugLog("Calc Rotation : " + calcRotation.ToString() + " and to UINT : " + (uint)calcRotation); // Calculate the distance for seconds to move int requiredSeconds = (int)(((math.distance2Coords((float)xPos, (float)xNew, (float)zPos, (float)zNew) / 0.176) / 500) * 0.9586); return(requiredSeconds); }
/// <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) { Output.Write("[ViewThread] Handle View For all Packet for charId : " + charId.ToString()); // Get or generate a View for the GoID ClientView view = client.viewMan.getViewForEntityAndGo(entityId, goId); DynamicArray content = new DynamicArray(); if (view.viewCreated == false) { Output.WriteDebugLog("Created View Id : " + view.ViewID.ToString()); // if view is new , add the viewId at the end (cause its creation) // Remove the 03 01 00 (as it was generate previosly) content.append(data); content.append(NumericalUtils.uint16ToByteArray(view.ViewID, 1)); content.append(0x00); // View Zero } else { // Update View content.append(NumericalUtils.uint16ToByteArray(view.ViewID, 1)); content.append(data); content.append(0x00); // View Zero Output.WriteDebugLog("Update View Id : " + view.ViewID.ToString()); } if (view.viewNeedsToBeDeleted == true) { content.append(0x01); content.append(0x00); content.append(0x01); // Comand (Delete) content.append(0x01); // NumViews (1 currently) content.append(0x00); content.append(NumericalUtils.uint16ToByteArray(view.ViewID, 1)); content.append(0x00); } // ToDo: handle viewId for packets (For creation it needs to be append to the end, for update at the start ) // ToDo: Complete this :) client.messageQueue.addObjectMessage(content.getBytes(), false); client.flushQueue(); Output.WriteLine("[World View Server] CharId: " + client.playerData.getCharID().ToString() + " )"); } } } }
private void FinalSendTo(IAsyncResult asyncResult) { try { socket.EndSend(asyncResult); } catch (Exception ex) { Output.WriteDebugLog("SendData Error: " + ex.Message); } }
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 byte[] getFinalData(ClientData playerData) { // TODO: Sim Time with Client (not real time) on every 4 Local SSEQ we send playerData.IncrementSseq(); this.neededAckSSeq = playerData.getSseq(); if ((NumericalUtils.ByteArrayToUint32(TimeUtils.getCurrentSimTime(), 1) - playerData.lastSimTimeUpdate) > 3) { timed = true; playerData.lastSimTimeUpdate = NumericalUtils.ByteArrayToUint32(TimeUtils.getCurrentSimTime(), 1); } playerData.getRPCShutDown(); if (timed) { if (playerData.waitForRPCShutDown == true) { content.append((byte)0xc2); } else { content.append((byte)0x82); } content.append(TimeUtils.getCurrentSimTime()); } else { if (playerData.waitForRPCShutDown == true) { content.append((byte)0x42); } else { content.append((byte)0x02); } } // Merge all Message together and generate the Final Packet Header generateObjectMessageData(); generateRpcMessageData(); Output.WriteDebugLog("PACKET DATA (getFinalData):" + StringUtils.bytesToString(content.getBytes())); return(content.getBytes()); }
private void sendMarginCharData(byte[] data, byte opcode, NetworkStream client, UInt16 shortAfterId, bool isLast) { // This Method will be used to send the real Data to the client // Format for general LoadCharacterReply Responses: // 10 00 00 00 <- everytime the same // 00 f9 76 04 <- uint32 Char ID // 00 00 00 09 <- uint32 number of Character Replys (just raise one up) // 00 05 <- viewData opcode (what data is inside) uint16 // 10 00 <- if it has Data it is 10 00 if not is just 00 00 (and no Data can follow up and packet ends here) // e1 00 <- short / uint16 data size // DATA numCharacterReplies++; PacketContent pak = new PacketContent(); pak.addByte(0x10); pak.addUint32(0, 1); pak.addUint32(newCharID, 1); pak.addUint16(shortAfterId, 1); pak.addUintShort(numCharacterReplies); if (isLast) { pak.addUintShort(1); } else { pak.addUintShort(0); } pak.addUintShort(opcode); if (data.Length > 0) { pak.addByteArray(new byte[] { 0x10, 0x00 }); pak.addUint16((UInt16)data.Length, 1); pak.addByteArray(data); } else { pak.addByteArray(new byte[] { 0x00, 0x00 }); } Output.WriteDebugLog("[MARGIN SERVER RESPONSE] for OPCODE " + opcode + " : " + StringUtils.bytesToString(pak.returnFinalPacket())); byte[] encryptedResponse = marginEncr.encrypt(pak.returnFinalPacket()); sendTCPVariableLenPacket(encryptedResponse, client); System.Threading.Thread.Sleep(50); }
// This method sends one packet at a time to the game client private void sendPacket(byte[] data) { if (this.deadSignals == 0) { //Output.WriteLine("[SEND PACKET] PSS: " + playerData.getPss().ToString() + " SSEQ : " + playerData.getSseq().ToString() + " CSEQ: " + playerData.getCseq().ToString()); try { socket.BeginSendTo(data, 0, data.Length, SocketFlags.None, Remote, new AsyncCallback(FinalSendTo), Remote); } catch (Exception ex) { #if DEBUG Output.WriteDebugLog("Socket Error " + ex.Message); #endif alive = false; } } }
private void ListenForAllClients() { byte[] byteTrue = new byte[4]; byteTrue[byteTrue.Length - 1] = 1; socket.IOControl(SIO_UDP_CONNRESET, byteTrue, null); serverport = 10000; udplistener = new IPEndPoint(IPAddress.Any, serverport); buffer = new byte[4096]; socket.Bind(udplistener); IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0); EndPoint Remote = sender; try { socket.BeginReceiveFrom(buffer, 0, buffer.Length, SocketFlags.None, ref Remote, new AsyncCallback(finalReceiveFrom), socket); }catch (Exception ex) { Output.WriteDebugLog("Exception Thrown ListenForAllClients " + ex.Message); } }
public LtVector3f RadnomPointInCircle(float xCurrent, float zCurrent, float radius) { // calc http://stackoverflow.com/questions/5531827/random-point-on-a-given-sphere // http://freespace.virgin.net/hugo.elias/routines/r_dist.htm - Distance LtVector3f newPos = new LtVector3f(); newPos.a = 0.0f; newPos.c = 0.0f; int randMax = 254; float angle = (float)(rand.Next(1, randMax) * (Math.PI * 2) / randMax); float distance = (float)Math.Sqrt(rand.Next(1, (int)radius) * 1.0 / randMax) * radius / 100; float x = (float)Math.Cos(angle) * distance + (xCurrent / 100); float z = (float)Math.Sin(angle) * distance + (zCurrent / 100); Output.WriteDebugLog("Distance : " + distance); newPos.a = x; newPos.c = z; return(newPos); }
private static void ParseContent(ref byte[] packetData) { buffer = null; buffer = packetData; offset = 0; //initialize to initial byte byte temp; temp = BufferHandler.readByte(ref packetData, ref offset); // Convert to Ack Flags BitArray AckFlags = NumericalUtils.byteToBitArray(temp); /* Flag Field * 1 - unknown / nothing * 2 - isAck (should always be ) * 3 - unknown currently * 4 - unknown currently * 5 - SERVERFLAGS_RESETRCC * 6 - CLIENTFLAGS_RESETDONE (so its done) * 7 - SERVERFLAG_SIMTIME (aka 0x82, 0xc2) */ if (AckFlags.Get(1) == false) { Output.WriteDebugLog("[WARNING] Packet has acked not set and is encrypted"); } if (AckFlags.Get(7) == true) { byte[] simTime = BufferHandler.readBytes(ref packetData, ref offset, 4); Store.currentClient.playerData.setClientSimTime(NumericalUtils.byteArrayToFloat(simTime, 1)); } if (AckFlags.Get(6) == true) { Output.WriteDebugLog("[CLIENT]CLIENTFLAGS_RESETDONE found - we can init new RCC Comm "); // Reset comm Store.currentClient.playerData.setCseq(0); Store.currentClient.playerData.setSseq(0); Store.currentClient.playerData.setPss(0x00); Store.currentClient.playerData.setOnWorld(false); Store.currentClient.playerData.setRPCShutDown(false); Store.currentClient.playerData.setRPCCounter(0); PlayerHandler handler = new PlayerHandler(); handler.processAttributes(); handler.processPlayerSetup(); } if (packetData.Length > 1 && AckFlags.Get(1) == true) //Not just ACK nor Resetting { if (packetData[offset] == 0x05) { offset = offset + 4; Output.writeToLogForConsole("Its a 05 Packet"); Store.currentClient.messageQueue.ackOnlyCount = Store.currentClient.messageQueue.ackOnlyCount + 1; Store.currentClient.flushQueue(); // We dont need a handler for 05 Packets (as there is only one as i see lol) } if (packetData[offset] == 0x03) // Is a 03 packet { offset++; offset = man03.parse(offset, ref buffer); } if (offset < packetData.Length) // There is no more info if we'r out of offset { if (packetData[offset] == 0x04) // Is a 04 packet { offset++; offset = man04.parse(offset, ref buffer); } } if (Store.currentClient.messageQueue.ObjectMessagesQueue.Count == 0 && Store.currentClient.messageQueue.RPCMessagesQueue.Count == 0) { // nothing to send ? we should really ack something then Store.currentClient.messageQueue.ackOnlyCount = Store.currentClient.messageQueue.ackOnlyCount + 1; Store.currentClient.flushQueue(); } } }
// Flush the MessageQueue Lists to the Client public void flushQueue() { // This resend the MessageQueue - should be called after parsing or after sending something out // or in a timed interval (keep alive for example) // Sends RAW MEssages sendRawMessages(); Output.WriteLine("[CLIENT] In Queue Messages : " + messageQueue.ObjectMessagesQueue.Count.ToString() + " Object and " + messageQueue.RPCMessagesQueue.Count.ToString() + " RPC Messages"); ArrayList worldPackets = new ArrayList(); WorldPacket packet = new WorldPacket(playerData); // Init encrypted Packet if we have MPM Messages if (messageQueue.RPCMessagesQueue.Count > 0 || messageQueue.ObjectMessagesQueue.Count > 0 && flushingQueueInProgress == false) { flushingQueueInProgress = true; // we currently dont know if we send something out so we need to proove that in a way if (messageQueue.ObjectMessagesQueue.Count > 0) { UInt16 sendingSSeq = playerData.calculateNextPossibleSseq(); lock (messageQueue.ObjectMessagesQueue.SyncRoot) { foreach (SequencedMessage messageObjects in messageQueue.ObjectMessagesQueue) { // Just append each message... if (messageObjects.getResendTime() >= TimeUtils.getUnixTimeUint32() || messageObjects.getResendTime() == 0) { // Check if this really save the resendtime or not messageObjects.increaseResendTime(); bool canAddThePak = packet.addObjectContent(messageObjects); if (canAddThePak == false) { packet.isFinal = true; // if one sub has a timed param set, we just set it here too worldPackets.Add(packet); // Start new packet and add it to the queue packet = new WorldPacket(playerData); packet.addRPCContent(messageObjects); } if (messageObjects.isTimed == true) { packet.timed = true; } } } } } // Workaround: complete the packet so we dont mix up if (packet.ObjectMessages.Count > 0) { packet.isFinal = true; worldPackets.Add(packet); packet = new WorldPacket(playerData); packet.timed = false; } if (messageQueue.RPCMessagesQueue.Count > 0) { lock (messageQueue.RPCMessagesQueue.SyncRoot) { foreach (SequencedMessage messageRPC in messageQueue.RPCMessagesQueue) { // First do stuff on messages // Just append each message... if (messageRPC.getResendTime() >= TimeUtils.getUnixTimeUint32() || messageRPC.getResendTime() == 0) { // Check if this really save the resendtime or not messageRPC.increaseResendTime(); if (packet.addRPCContent(messageRPC) == false) { packet.isFinal = true; worldPackets.Add(packet); // Start new packet and add it to the queue packet = new WorldPacket(playerData); packet.addRPCContent(messageRPC); } if (messageRPC.isTimed == true) { packet.timed = true; } } } } } // Check if the current not finalize packet has content and needs to be send if ((packet.isFinal == false) && (packet.ObjectMessages.Count > 0 || packet.RPCMessages.Count > 0)) { worldPackets.Add(packet); } } // We have nothing - but we should really ack this if (messageQueue.ackOnlyCount > 0) { for (int i = 0; i < messageQueue.ackOnlyCount; i++) { WorldPacket ackPacket = new WorldPacket(playerData); packet.isFinal = true; packet.timed = false; worldPackets.Add(ackPacket); } messageQueue.ackOnlyCount = 0; } // We have now PacketObjects - time to send them if (worldPackets.Count > 0) { Output.WriteLine("[CLIENT] Flush the final Queue with " + worldPackets.Count.ToString() + " Packets"); foreach (WorldPacket thePacket in worldPackets) { playerData.IncrementSseq(); byte[] finalData = thePacket.getFinalData(playerData); Output.WritePacketLog(StringUtils.bytesToString(finalData), "SERVER", playerData.getPss().ToString(), playerData.getCseq().ToString(), playerData.getSseq().ToString()); byte[] encryptedData = cypher.encrypt(finalData, finalData.Length, playerData.getPss(), playerData.getCseq(), playerData.getSseq()); sendPacket(encryptedData); Output.WriteDebugLog("PACKET SEND FINALLY (WC AFTER sendPacket):" + StringUtils.bytesToString(finalData)); } } flushingQueueInProgress = false; }
private void sendMarginCharData(byte[] data, byte opcode, NetworkStream client) { // This Method will be used to send the real Data to the client // Format for general LoadCharacterReply Responses: // 10 00 00 00 <- everytime the same // 00 f9 76 04 <- uint32 Char ID // 00 00 00 09 <- uint32 number of Character Replys (just raise one up) // 00 05 <- viewData opcode (what data is inside) uint16 // 10 00 <- if it has Data it is 10 00 if not is just 00 00 (and no Data can follow up and packet ends here) // e1 00 <- short / uint16 data size // DATA byte[] header = { 0x10, 0x00, 0x00, 0x00 }; // Raise one up loadCharCounter++; // Add the counter byte[] counterByte = new byte[4]; counterByte = NumericalUtils.uint32ToByteArray(loadCharCounter, 1); // get the datasize for the packet byte[] dataSize = NumericalUtils.uint16ToByteArray((UInt16)data.Length, 1); // charId byte[] charID = NumericalUtils.uint32ToByteArray(this.newCharID, 0); // viewData code byte[] responseCode = { 0x00, opcode }; string pakData = StringUtils.bytesToString_NS(header) + StringUtils.bytesToString_NS(charID) + StringUtils.bytesToString_NS(counterByte) + StringUtils.bytesToString_NS(responseCode); string hasData; // this needs improvement... if (data.Length == 0 && opcode == 0x01) { hasData = "0000"; } else { hasData = "1000" + StringUtils.bytesToString_NS(dataSize) + StringUtils.bytesToString_NS(data); } pakData += hasData; PacketContent pak = new PacketContent(); // Dump the Packet Data to see whats in //Console.WriteLine("Response Load Pak : " + pakData); // Do the viewData byte[] response = StringUtils.hexStringToBytes(pakData); Output.WritePacketLog(StringUtils.bytesToString(response), "MARGINSERVER", "0", "0", "0"); Output.WriteDebugLog("[MARGIN SERVER RESPONSE] for OPCODE " + opcode + " : " + StringUtils.bytesToString(response)); byte[] encryptedResponse = marginEncr.encrypt(response); sendTCPVariableLenPacket(encryptedResponse, client); System.Threading.Thread.Sleep(50); }