Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions airmash/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ def __init__(self, enable_debug=False, enable_chat=True):

def on(self, key, handler=None):
def decorate(handler):
self._handlers[key] = handler
keys = [key] if isinstance(key, str) else key
for k in keys:
self._handlers[k] = handler

if handler is None:
return decorate
Expand Down Expand Up @@ -116,6 +118,10 @@ def process_message(self, message):
self.send(cmd)

self.connected = True

Mob.current_clock = message.clock
Player.current_clock = message.clock

return self._call_handler(message)

if message.command == 'SERVER_MESSAGE':
Expand Down Expand Up @@ -176,7 +182,8 @@ def process_message(self, message):
if message.command == 'PLAYER_FIRE':
for projectile in message.projectiles:
self._debug_print(packets.DEBUG_ACTION, u"New projectile of type {}".format(projectile.type))
self.projectiles[projectile.id] = Mob(projectile.id, self.players[message.id], projectile)
self.projectiles[projectile.id] = Mob(
projectile.id, self.players[message.id], projectile, clock=message.clock)
return self._call_handler(message)

if message.command == 'EVENT_STEALTH':
Expand All @@ -193,9 +200,11 @@ def process_message(self, message):
self._debug_print(packets.DEBUG_ACTION, u"{} uses repel. {} self.players and {} self.projectiles repelled.".format(self.players[message.id].name, len(message.players), len(message.mobs)))
for projectile in message.mobs:
if projectile.id in self.projectiles:
self.projectiles[projectile.id].update(projectile, new_owner=self.players[message.id])
self.projectiles[projectile.id].update(
projectile, new_owner=self.players[message.id], clock=message.clock)
else:
self.projectiles[projectile.id] = Mob(projectile.id, self.players[message.id], projectile)
self.projectiles[projectile.id] = Mob(
projectile.id, self.players[message.id], projectile, clock=message.clock)
return self._call_handler(message)

return self._call_handler(message)
Expand All @@ -208,7 +217,7 @@ def process_message(self, message):

if message.command == 'PLAYER_LEAVE':
self._debug_print(packets.DEBUG_ACTION, u"{} left".format(self.players[message.id].name))
self.players[message.id].online = False
self.players[message.id].active = False
return self._call_handler(message)

if message.command == 'PLAYER_NEW':
Expand Down Expand Up @@ -242,7 +251,7 @@ def process_message(self, message):
self.projectiles[message.id].update(message)
else:
self._debug_print(packets.DEBUG_INFO, u"Mob type of {} does not exist? {}".format(message.type, message.id))
self.projectiles[message.id] = Mob(message.id, None, message)
self.projectiles[message.id] = Mob(message.id, None, message, clock=message.clock)
return self._call_handler(message)

if message.command in ['MOB_DESPAWN', 'MOB_DESPAWN_COORDS']:
Expand Down
19 changes: 16 additions & 3 deletions airmash/mob.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
class Mob():
def __init__(self, id, owner, data={}):
self.online = True
current_clock = 0

def __init__(self, id, owner, data={}, clock=0):
self.clock = clock
Mob.current_clock = clock
self.active = True
self.id = id
self.owner = owner
self.active = True
self._handlers = {}
self.update(data)

@property
def age(self):
return (Mob.current_clock - self.clock) / 1e6

def __str__(self):
owner = self.owner.name if self.owner else 'Unknown'
return f'id:{self.id} age:{self.age:.1f} pos:({self.posX:.1f}, {self.posY:.1f})'

def despawn(self):
self.active = False
self._handle_change('despawn', True, False)
Expand All @@ -20,6 +31,8 @@ def update(self, data, new_owner=None):

old = self.__dict__.copy()

self.clock = self._get_default(data, 'clock', 0)
Mob.current_clock = self.clock
self.type = self._get_default(data, 'type', 0)
self.posX = self._get_default(data, 'posX', 0)
self.posY = self._get_default(data, 'posY', 0)
Expand Down
12 changes: 11 additions & 1 deletion airmash/player.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ def ks(player, k, a, b):
print("[{}] {}: {}".format(player.name, k, a))

class Player():

current_clock = 0

def __init__(self, id, data={}):
self.online = True
self.active = True
self.id = id
self._handlers = {}
self.update(data)
Expand All @@ -14,11 +17,18 @@ def __init__(self, id, data={}):

#self._handlers['upgrades'] = ks
#self._handlers['keystate'] = ks
@property
def age(self):
return (Player.current_clock - self.clock) / 1e6

def __str__(self):
return f'{self.name} id:{self.id} age:{self.age:.1f} pos:({self.posX:.1f}, {self.posY:.1f})'

def update(self, data):
old = self.__dict__.copy()

self.clock = self._get_default(data, 'clock', 0)
Player.current_clock = self.clock
self.status = self._get_default(data, 'status', 0)
self.level = self._get_default(data, 'level', 0)
self.name = self._get_default(data, 'name', "")
Expand Down
101 changes: 101 additions & 0 deletions gui-client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import os
import sys
from threading import Thread
from time import sleep

import pygame

from airmash.client import Client

client = Client(enable_debug=False, enable_chat=False)


@client.on('PLAYER_HIT')
def on_hit(client, message):
for player in message.players:
if player.id == client.player.id:
print("Uh oh! I've been hit!")


@client.on(['MOB_DESPAWN', 'MOB_DESPAWN_COORDS', 'MOB_UPDATE', 'MOB_UPDATE_STATIONARY'])
def md(client, message):
print(message)


kwargs = dict(
name='z',
flag='GB',
region='eu',
room='ffa1',
enable_trace=False
)

t = Thread(target=client.connect, kwargs=kwargs)
t.start()

size = width, height = 900, 1000
black = 0, 0, 0
white = 255, 255, 255
red = 255, 0, 0
green = 0, 255, 0
blue = 0, 0, 255

player_size = 50
projectile_size = 20

os.environ['SDL_VIDEO_WINDOW_POS'] = "0,20"
pygame.init()
font = pygame.font.SysFont('', 20)
clock = pygame.time.Clock()
screen = pygame.display.set_mode(size)

keys = {
pygame.K_w: 'UP',
pygame.K_s: 'DOWN',
pygame.K_a: 'LEFT',
pygame.K_d: 'RIGHT',
pygame.K_SPACE: 'FIRE',
pygame.K_LSHIFT: 'SPECIAL',
}

while not client.connected:
sleep(0.1)


def draw(items, colour, size=player_size):
for item in items:
if not item.active:
continue
x = item.posX - me.posX + (width / 2.0)
y = item.posY - me.posY + (height / 2.0)
if 0 < x < width and 0 < y < height:
pygame.draw.rect(screen, colour, (x, y, size, size))
textsurface = font.render(str(item), True, white)
screen.blit(textsurface, (x, y))


while 1:

for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()

elif event.type == pygame.KEYDOWN:
d = keys.get(event.key)
if d:
client.key(d, True)

elif event.type == pygame.KEYUP:
d = keys.get(event.key)
if d:
client.key(d, False)

screen.fill(black)

me = client.player
draw([me], blue)
draw(client.players.values(), green)
draw(client.projectiles.values(), red, size=20)

pygame.display.flip()
clock.tick(30)