Skip to content

Commit

Permalink
All of the RCON packets are build using the BasePacket class
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucino772 committed Apr 26, 2021
1 parent b19bada commit e16effb
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 131 deletions.
118 changes: 60 additions & 58 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 26 additions & 30 deletions mojang/api/net/rcon/client.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import struct
import socket
import select

from ..common.packet import Packet
from .packets.login import LoginRequest, LoginResponse
from .packets.command import CommandRequest, CommandResponse
from ..common.packet import BasePacket
from .packets.login import LoginRequestPacket, LoginResponsePacket
from .packets.command import CommandRequestPacket, CommandResponsePacket

class RconClient:

Expand All @@ -20,50 +19,47 @@ def _new_id(self):
self.__id__ += 1
return self.__id__

def _recv(self, cls: Packet = None):
if select.select([self.__sock], [], [], 1)[0]:
with self.__sock.makefile('rb') as stream:
packet_length = struct.unpack('<i', stream.read(4))[0]

data = b''
while len(data) < packet_length:
_data = stream.read(packet_length - len(data))
if _data:
data += _data
if cls:
return cls.create_from(data)
else:
return data
def _recv(self, cls: BasePacket = None):
with self.__sock.makefile('rb') as stream:
packet_length = struct.unpack('<i', stream.read(4))[0]

data = b''
while len(data) < packet_length:
_data = stream.read(packet_length - len(data))
if _data:
data += _data
if cls:
return cls.from_bytes(data)
else:
return data

def _send(self, packet: Packet):
if select.select([], [self.__sock], [], 1)[1]:
with self.__sock.makefile('wb') as stream:
data = bytes(packet)
stream.write(struct.pack('<i', len(data)))
stream.write(data)

def _send(self, packet: BasePacket):
with self.__sock.makefile('wb') as stream:
stream.write(struct.pack('<i', len(packet.data)))
stream.write(packet.data)

def connect(self):
self.__sock.connect(self.__host)
self.__sock.setblocking(False)
self.__sock.settimeout(1)
self._authenticate()

def _authenticate(self):
packet = LoginRequest(id=self._new_id, payload=self.__password)
packet = LoginRequestPacket(id=self._new_id, payload=self.__password)
self._send(packet)

r_packet = self._recv(LoginResponse)
r_packet = self._recv(LoginResponsePacket)

if r_packet.type != 2 or r_packet.id == -1:
raise Exception('Authentication Failed !')

def run_cmd(self, cmd: str):
packet = CommandRequest(id=self._new_id, payload=cmd)
packet = CommandRequestPacket(id=self._new_id, payload=cmd)
self._send(packet)

response = ''
try:
while 1:
r_packet = self._recv(CommandResponse)
r_packet = self._recv(CommandResponsePacket)
if r_packet is None:
break

Expand Down
36 changes: 14 additions & 22 deletions mojang/api/net/rcon/packets/command.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,14 @@
import struct

from ...common.packet import Packet

class CommandRequest(Packet):
type: int = 2
id: int
payload: str

def _bytes(self):
encoded_payload = self.payload.encode('ascii')
return struct.pack('<ii{}s2s'.format(len(encoded_payload)), self.id, self.type, encoded_payload, b'\0\0')

class CommandResponse(Packet):
type: int
id: int
payload: str

@classmethod
def _parse(cls, buffer: bytes):
request_id, _type, payload = struct.unpack_from('<ii{}s'.format(len(buffer) - 10), buffer)
return dict(type=_type,id=request_id,payload=payload.decode('ascii'))
from ...common.packet import BasePacket
from ...common.types import *

class CommandRequestPacket(BasePacket):
id: int = LittleEndianInt32()
type: int = LittleEndianInt32(default=2)
payload: str = NullTerminatedString()
pad: int = Byte(default=0x00)

class CommandResponsePacket(BasePacket):
id: int = LittleEndianInt32()
type: int = LittleEndianInt32()
payload: str = NullTerminatedString()
pad: int = Byte()
33 changes: 12 additions & 21 deletions mojang/api/net/rcon/packets/login.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,12 @@
import struct

from ...common.packet import Packet

class LoginRequest(Packet):
type: int = 3
id: int
payload: str

def _bytes(self):
encoded_payload = self.payload.encode('ascii')
return struct.pack('<ii{}s2s'.format(len(encoded_payload)), self.id, self.type, encoded_payload, b'\0\0')

class LoginResponse(Packet):
type: int
id: int

@classmethod
def _parse(cls, buffer: bytes):
request_id, _type, _ = struct.unpack_from('<ii{}s'.format(len(buffer) - 10), buffer)
return dict(type=_type,id=request_id)
from ...common.packet import BasePacket
from ...common.types import *

class LoginRequestPacket(BasePacket):
id: int = LittleEndianInt32()
type: int = LittleEndianInt32(default=3)
payload: str = NullTerminatedString()
pad: int = Byte(default=0x00)

class LoginResponsePacket(BasePacket):
id: int = LittleEndianInt32()
type: int = LittleEndianInt32()

0 comments on commit e16effb

Please sign in to comment.