From b303320d6905376e1ca24a185ff9749d421b789d Mon Sep 17 00:00:00 2001 From: HipsterCat Date: Thu, 28 Feb 2019 04:01:03 +0100 Subject: [PATCH] Many things, I guess --- dpnet/CFrame.py | 3 +- dpnet/netserver.py | 123 ++++++++++++++++++++++++++++++++++--------- giants/map.py | 4 ++ giants/player.py | 20 +++++-- plugins/greetings.py | 3 ++ server.py | 20 ++++++- 6 files changed, 141 insertions(+), 32 deletions(-) diff --git a/dpnet/CFrame.py b/dpnet/CFrame.py index d653781..2c1ed31 100644 --- a/dpnet/CFrame.py +++ b/dpnet/CFrame.py @@ -63,8 +63,7 @@ class CFrame: packet.putByte(self.Retry) packet.putByte(self.NSeq) packet.putByte(self.NRecv) - packet.putByte(0) # padding - packet.putByte(0) # padding + packet.putShort(0) # padding packet.putULong(self.Timestamp) else: packet.putByte(self.MsgID) diff --git a/dpnet/netserver.py b/dpnet/netserver.py index 173e5b9..de0991f 100644 --- a/dpnet/netserver.py +++ b/dpnet/netserver.py @@ -15,6 +15,7 @@ from utils.logger import setup_logger from giants.player import Player, PlayerPhases import time from giants import APPLICATION_GUID +import random from .DN_MSG_INTERNAL_SEND_CONNECT_INFO import DN_MSG_INTERNAl_SEND_CONNECT_INFO import asyncio @@ -177,7 +178,7 @@ class Netserver(asyncio.DatagramProtocol): for b1, b2 in zip(b1, b2): result.append(b1 ^ b2) return result - player.id = struct.unpack(">L", bxor(struct.pack("L", bxor(struct.pack(" %s (DFRAME)", addr[0], addr[1], data.getvalue().hex()) return - if not dframe.Seq == session.next_expected_seq: - logger.error("%s unexpected SEQ. Got %s, expected %s", addr, dframe.Seq, session.next_expected_seq) - #return if dframe.Control & DFrame.PACKET_CONTROL_END_STREAM: + logger.debug("%s:%s > %s (END_STREAM)", addr[0], addr[1], data.getvalue().hex()) if not session: logger.error("Received a END STREAM packet for a non fully connected session") - return - # disconnect + session = Session(self.remotesocket) + session.ip = addr[0] + session.port = addr[1] + session.SessID = dframe.SessID + session.next_send = dframe.NRcv + session.next_expected_seq = dframe.Seq+1 + + session.send_cframe_sack() resp = DFrame() resp.Command = DFrame.PACKET_COMMAND_DATA | DFrame.PACKET_COMMAND_NEW_MSG | DFrame.PACKET_COMMAND_END_MSG | DFrame.PACKET_COMMAND_RELIABLE | DFrame.PACKET_COMMAND_SEQUENTIAL resp.Control = DFrame.PACKET_CONTROL_END_STREAM resp.Seq = dframe.NRcv resp.NRcv = session.next_send + logger.debug(" %s:%s < %s (END_STREAM)", session.ip, session.port, resp.to_packet().getvalue().hex()) session.send(resp) - session.send_cframe_sack() - # TODO: broadcast session has disconnected - self.addrs.remove(session) + if self.get_session(addr): + self.addrs.remove(session) + return + + if not dframe.Seq == session.next_expected_seq: + logger.error("%s unexpected SEQ. Got %s, expected %s", addr, dframe.Seq, session.next_expected_seq) + #return + + if dframe.Control & DFrame.PACKET_CONTROL_KEEPALIVE_OR_CORRELATE: pass #session.send_dframe_keepalive() @@ -354,8 +366,6 @@ class Netserver(asyncio.DatagramProtocol): player.phase = PlayerPhases.DN_ACK_CONNECT_INFO await self.server.add_player(player) - #player.session.send_cframe_sack() - await player.session.send_gamedata(b'\x3c'+struct.pack(" + objid = "75" + plix = "01" + model = "4b" + async def spawn(objid, plix, model): + await player.session.send_gamedata(bytes.fromhex("05"+plix+objid+"0000"+model+"00000000"), acknow=False) + await player.session.send_gamedata(bytes.fromhex("0a32000000"+plix+objid+"000001"+model+"0000000000000000000000000000000000000000000000000000000000000000000000000000000a12000000"+plix+objid+"0000"+model+"020000000000000000"), acknow=False) + await spawn(objid, plix, model) + + + #for i in range(76, 200): + # await spawn(struct.pack(" # \x9c\x53\xf4\xdd: Three Way Island - Canyons diff --git a/giants/player.py b/giants/player.py index bcd0a85..7f65807 100644 --- a/giants/player.py +++ b/giants/player.py @@ -2,6 +2,7 @@ from .entity import Entity import random import struct from . import ChatColor, ChatType +from dpnet.DFrame import DFrame class PlayerPhases: @@ -11,6 +12,7 @@ class PlayerPhases: DN_INTERNAL_MESSAGE_PLAYER_CONNECT_INFO_EX = 3 DN_SEND_CONNECT_INFO = 4 DN_ACK_CONNECT_INFO = 5 + INGAME = 6 class Player(Entity): @@ -18,15 +20,16 @@ class Player(Entity): super().__init__() self.name = name self.session = session - self.team = 4 + self.team = 2 self.score = 0 - self.id = random.getrandbits(32) + self.id = random.getrandbits(16) self.phase = PlayerPhases.NONE self.ping = 1 async def change_team(self, newteam): self.team = newteam - await self.session.send_gamedata(b"\x10"+struct.pack("