public void handlePacket(MessageData data) { var buffer = data.Get <byte[]>("data"); var source = data.Get <EndPoint>("source"); var stream = new MemoryStream(buffer); var reader = new BinaryReader(stream); var time = data.Get <DateTime>("time"); var delay = (DateTime.Now - time).TotalMilliseconds; var delay2 = DateTime.Now; try { while (stream.Position < stream.Length) { var origin = 0; var len = 0; if (_bytesRead == 0) { _totalBytes = 0; try { _totalBytes = reader.ReadInt32(); } catch { _totalBytes = 0; } //Log.Info("GOT A PACKET OF SIZE " + _totalBytes.ToString("X")); if (_totalBytes == 0xC8) { _totalBytes = 0; break; } if (_totalBytes > (256 * 1024)) { Log.Error("LENGTH IS XBOX"); break; } if (_totalBytes == 0 || _totalBytes < 0) { //TCPHandler.sendPacket(message, client); MessageData packet = new MessageData("none"); packet["data"] = new byte[4]; packet["cid"] = data.Get <string>("cid"); TCPHandler.Net_TcpSend(packet); continue; } _messageBuffer = new MemoryStream(); origin += 4; len -= 4; } len += Math.Min((buffer.Length - (int)stream.Position), (_totalBytes - _bytesRead)); var newBytes = reader.ReadBytes(len); _messageBuffer.Write(newBytes, 0, len); _bytesRead += len; if (_bytesRead > _totalBytes) { //Debugger.Break(); } if (_bytesRead >= _totalBytes) { _bytesRead = 0; _messageBuffer.Position = 0; var breader = new BinaryReader(_messageBuffer); _totalBytes--; var pdtype = breader.ReadByte(); var encrypted = (pdtype == 1); // can be 0, 1 and 0xFF var ptype = 0xFF; byte[] pdata = null; if (pdtype == 0xFF) { // TODO: handle this one Log.Debug("Got a 0xFF pdtype!"); //return; continue; } var initTime = DateTime.Now; if (!encrypted) { ptype = breader.ReadByte(); _totalBytes -= 1; pdata = breader.ReadBytes(_totalBytes); } else { try { var key = GetGlobalKey(data); var iv = DWCrypto.CalculateInitialVector(breader.ReadUInt32()); var edata = breader.ReadBytes(_totalBytes - 4); var ddata = DWCrypto.Decrypt(iv, key, edata); var dstream = new MemoryStream(ddata); var dreader = new BinaryReader(dstream); // TODO: find out why this hash isn't just truncated SHA-1 var hash = dreader.ReadUInt32(); ptype = dreader.ReadByte(); pdata = dreader.ReadBytes((int)(dstream.Length - 5)); dreader.Close(); dstream.Close(); } catch { } } var initTime2 = DateTime.Now; var delay3 = (DateTime.Now - delay2).TotalMilliseconds; //Log.Debug("Received a " + _totalBytes + " byte packet (type " + ptype + ") from DemonWare - delay " + delay + "ms. delay after reading " + delay3 + "ms."); /* * var message = Messages.NewMessage("dw.packet-received"); * message["data"] = pdata; * message["type"] = ptype; * message["crypt"] = encrypted; * message["source"] = source; * message["cid"] = data["cid"]; * message["delay"] = delay; * message["time"] = DateTime.Now; * message.SendNow(); */ MessageData message = new MessageData("none"); message["data"] = pdata; message["type"] = ptype; message["crypt"] = encrypted; message["source"] = source; message["cid"] = data["cid"]; message["ci"] = data["ci"]; message["delay"] = delay; message["time"] = DateTime.Now; redirectPacket(message); /*var msec = (int)((DateTime.Now - initTime).TotalMilliseconds); * var state = GetPerfState(ptype); * state.Add(msec); * * msec = (int)((DateTime.Now - initTime2).TotalMilliseconds); * var state2 = GetPerfState(ptype + 1000); * state2.Add(msec); * * Log.Debug("service " + ptype + " min " + state.Min + "/" + state2.Min + " max " + state.Max + "/" + state2.Max);*/ } } } catch (Exception ex) { Log.Error(ex.ToString()); // disconnect to prevent further pollution of system TCPHandler.ForceDisconnect(data); } reader.Close(); }
private void redirectPacket(MessageData data) { data.Arguments["handled"] = false; var type = data.Get <int>("type"); var crypt = data.Get <bool>("crypt"); bool routed = false; try { if (!crypt && (type == 28 || type == 12 || type == 26)) { DWAuther.DW_PacketReceived(data); routed = true; //Log.Debug("got auth packet"); } if (crypt && type == 28) { DWGroups.DW_PacketReceived(data); routed = true; } if (type == 7) { DWLobby.DW_PacketReceived(data); routed = true; //Log.Debug("got lobby packet"); } if (type == 6) { DWMessaging.DW_PacketReceived(data); routed = true; //Log.Debug("got service packet"); } if (type == 21) { DWMatch.DW_PacketReceived(data); routed = true; //Log.Debug("got match packet"); } if ((type == 10) || (type == 18) || (type == 23) || (type == 8 || type == 50 || type == 4 || type == 58)) { DWStorage.DW_PacketReceived(data); routed = true; //Log.Debug("got storage packet"); } if (type == 12 && crypt) { DWTitles.DW_PacketReceived(data); routed = true; //Log.Debug("got Title packet"); } if (type == 8) { DWProfiles.DW_PacketReceived(data); routed = true; } if (type == 27) { DWDML.DW_PacketReceived(data); } if (type == 67) { DWEventLog.DW_PacketReceived(data); } } catch (Exception e) { Log.Error("Exception: " + e.ToString()); } /*if(routed == false) * { * Log.Debug("UNHANDLED PACKET: " + type); * }*/ try { if (crypt && !data.Get <bool>("handled")) { DWRouter.Unknown(data, DWRouter.GetMessage(data)); } } catch { Log.Error("UNKNOWN FAILED, THIS CONNECTION CAN BE CONSIDERED DEAD."); // disconnect to prevent pollution of system TCPHandler.ForceDisconnect(data); } }