From: Elijah Cohen Date: Wed, 17 Apr 2019 21:32:32 +0000 (-0500) Subject: preliminary node nonsenses X-Git-Url: https://git.eli173.com/?a=commitdiff_plain;h=b5e8a9b9476eefdc6be86447b265866f59521215;p=pong_br preliminary node nonsenses --- diff --git a/.gitignore b/.gitignore index 75fc14d..9a77fd5 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,9 @@ lib/ /web/socket.js~ /web/test.html~ /web/test.js~ +/server/game.js~ +/server/node_modules/* +server/node_modules/* +/server/gamestate.js~ +/server/matchmaker.js~ +/server/player.js~ diff --git a/connector.py b/connector.py deleted file mode 100644 index a3caa64..0000000 --- a/connector.py +++ /dev/null @@ -1,10 +0,0 @@ - - -import asyncio -import websockets -import threading - - -async def getconnection(websocket, path): - - diff --git a/game.py b/game.py deleted file mode 100644 index b6aa439..0000000 --- a/game.py +++ /dev/null @@ -1,33 +0,0 @@ - - -SPF = 0.5 # half second for testing purposes -# MS_PER_FRAME = 67 # 15 fps? - - -import threading - -# not a (subclass of) thread, all this has to be is a timer that calls itself or whatever, hope it doesn't take too long to run or whatever - -import gamestate - -class Game(): - def __init__(self, players): - self.players = players - self.game_state = gamestate.GameState() - for player in self.players: # CAUTION HERE, MIGHT NEED TO MODIFY - player.run() - def run(self): - threading.Timer(SPF, self.run).start() - # okay, things to do here: - # check all the inputs in the player classes - # update global game state - # send data to players - inputs = [] - for idx, val in enumerate(self.players): - inputs.append(val.get_status()) - self.game_state.update_state(inputs) - self.game_state.advance_frame() - state = self.game_state.get_state() - for player in self.players: - player.send_data(state) - print(state) diff --git a/gamestate.py b/gamestate.py deleted file mode 100644 index f20f2b8..0000000 --- a/gamestate.py +++ /dev/null @@ -1,12 +0,0 @@ - - -class GameState(): - def __init__(self): - self.inputs = [] - def update_state(self, inputs): - self.inputs = inputs - def get_state(self): - return ''.join(self.inputs) - def advance_frame(self): - pass - diff --git a/main.py b/main.py deleted file mode 100644 index c146580..0000000 --- a/main.py +++ /dev/null @@ -1,9 +0,0 @@ - - - -import matchmaker - - - -if __name__ == "__main__": - mm = matchmaker.Matchmaker() diff --git a/matchmaker.py b/matchmaker.py deleted file mode 100644 index 3d56670..0000000 --- a/matchmaker.py +++ /dev/null @@ -1,38 +0,0 @@ - -WS_HOST = 'localhost' -WS_PORT = 6789 -NUM_PLAYERS = 4 - -import asyncio -import websockets -import threading - -import logging - -logger = logging.getLogger('websockets') -logger.setLevel(logging.INFO) -logger.addHandler(logging.StreamHandler()) - -import player -import game - -class Matchmaker(): - def manage_incoming(self,websocket, path): - # init a player, etc etc - new_player = player.Player(websocket) - self.players.append(new_player) - if len(self.players) > (NUM_PLAYERS - 1): # shenanigans to fix potential problem of stranding some (n+1)th player - with self.lock: - new_game = game.Game(self.players[:NUM_PLAYERS]) - new_game.run() - self.players = self.players[NUM_PLAYERS:] - print("did it") - def __init__(self): - # todo: this is where I initialise the listening stuff for websockets, where I pass manage_incoming (or whatev) to the thing - self.players = [] - self.lock = threading.Lock() - async def manager(ws,p): - self.manage_incoming(ws,p) - start_server = websockets.serve(manager,WS_HOST,WS_PORT) - asyncio.get_event_loop().run_until_complete(start_server) - asyncio.get_event_loop().run_forever() diff --git a/old/connector.py b/old/connector.py new file mode 100644 index 0000000..a3caa64 --- /dev/null +++ b/old/connector.py @@ -0,0 +1,10 @@ + + +import asyncio +import websockets +import threading + + +async def getconnection(websocket, path): + + diff --git a/old/game.py b/old/game.py index 4a2a507..b6aa439 100644 --- a/old/game.py +++ b/old/game.py @@ -1,10 +1,33 @@ -import websockets + +SPF = 0.5 # half second for testing purposes +# MS_PER_FRAME = 67 # 15 fps? + + import threading -class GamePlayer(threading.Thread): +# not a (subclass of) thread, all this has to be is a timer that calls itself or whatever, hope it doesn't take too long to run or whatever + +import gamestate + +class Game(): def __init__(self, players): - threading.Thread.__init__() self.players = players + self.game_state = gamestate.GameState() + for player in self.players: # CAUTION HERE, MIGHT NEED TO MODIFY + player.run() def run(self): - print("starting a thread or whatever: " + name) + threading.Timer(SPF, self.run).start() + # okay, things to do here: + # check all the inputs in the player classes + # update global game state + # send data to players + inputs = [] + for idx, val in enumerate(self.players): + inputs.append(val.get_status()) + self.game_state.update_state(inputs) + self.game_state.advance_frame() + state = self.game_state.get_state() + for player in self.players: + player.send_data(state) + print(state) diff --git a/old/gamestate.py b/old/gamestate.py new file mode 100644 index 0000000..f20f2b8 --- /dev/null +++ b/old/gamestate.py @@ -0,0 +1,12 @@ + + +class GameState(): + def __init__(self): + self.inputs = [] + def update_state(self, inputs): + self.inputs = inputs + def get_state(self): + return ''.join(self.inputs) + def advance_frame(self): + pass + diff --git a/old/main.py b/old/main.py new file mode 100644 index 0000000..c146580 --- /dev/null +++ b/old/main.py @@ -0,0 +1,9 @@ + + + +import matchmaker + + + +if __name__ == "__main__": + mm = matchmaker.Matchmaker() diff --git a/old/matchmaker.py b/old/matchmaker.py index 53cb72a..3d56670 100644 --- a/old/matchmaker.py +++ b/old/matchmaker.py @@ -1,30 +1,38 @@ +WS_HOST = 'localhost' +WS_PORT = 6789 +NUM_PLAYERS = 4 + import asyncio import websockets import threading -import pbr_constants +import logging + +logger = logging.getLogger('websockets') +logger.setLevel(logging.INFO) +logger.addHandler(logging.StreamHandler()) + +import player +import game class Matchmaker(): + def manage_incoming(self,websocket, path): + # init a player, etc etc + new_player = player.Player(websocket) + self.players.append(new_player) + if len(self.players) > (NUM_PLAYERS - 1): # shenanigans to fix potential problem of stranding some (n+1)th player + with self.lock: + new_game = game.Game(self.players[:NUM_PLAYERS]) + new_game.run() + self.players = self.players[NUM_PLAYERS:] + print("did it") def __init__(self): - self.lock = threading.Lock() + # todo: this is where I initialise the listening stuff for websockets, where I pass manage_incoming (or whatev) to the thing self.players = [] - async def get_game(self,p): - with self.lock: - self.players.append(p) - if len(self.players) ==pbr_constants.num_players: - self.new_game() - def new_game(self): - with self.lock: - print(self.players) - - self.players = [] - - - - - - - -if __name__=="__main__": - mm = Matchmaker() + self.lock = threading.Lock() + async def manager(ws,p): + self.manage_incoming(ws,p) + start_server = websockets.serve(manager,WS_HOST,WS_PORT) + asyncio.get_event_loop().run_until_complete(start_server) + asyncio.get_event_loop().run_forever() diff --git a/old/player.py b/old/player.py new file mode 100644 index 0000000..b061e88 --- /dev/null +++ b/old/player.py @@ -0,0 +1,21 @@ + + +import asyncio +import websockets +import threading + +# planning: +# I think I can properly initialise the async websocket stuff in the init method, then the other methods will probably be fine? There may be problems with send_data and asyncio stuff, but get_status is definitely fine as-is +class Player(): + def __init__(self, socket): + self.socket = socket + self.status = 'x' + self.status_lock = threading.Lock() + def send_data(self, data): + # to be used by the game thread thingy + asyncio.run(self.socket.send(data)) + def get_status(self): + with self.status_lock: + stat = self.status + self.status = 'x' + return stat diff --git a/player.py b/player.py deleted file mode 100644 index b061e88..0000000 --- a/player.py +++ /dev/null @@ -1,21 +0,0 @@ - - -import asyncio -import websockets -import threading - -# planning: -# I think I can properly initialise the async websocket stuff in the init method, then the other methods will probably be fine? There may be problems with send_data and asyncio stuff, but get_status is definitely fine as-is -class Player(): - def __init__(self, socket): - self.socket = socket - self.status = 'x' - self.status_lock = threading.Lock() - def send_data(self, data): - # to be used by the game thread thingy - asyncio.run(self.socket.send(data)) - def get_status(self): - with self.status_lock: - stat = self.status - self.status = 'x' - return stat diff --git a/server/game.js b/server/game.js new file mode 100644 index 0000000..9241cbe --- /dev/null +++ b/server/game.js @@ -0,0 +1,25 @@ + +const GameState = require('./gamestate.js'); + +function Game(players) { + this.players = players; + this.state = new GameState(); + this.timeout = null; +} + +Game.prototype.start = function(ms) { + this.timeout = setInterval(this.getNextFrame, ms); +} + +Game.prototype.getNextFrame = function() { + // + var inputs = this.players.map(function(p) {return p.get_status();}); + this.state.updateState(inputs); + var state = this.state.getState(); + for(var i=0; i NUM_PLAYERS) { + // is the slicing necessary? I'm not sure I understand js's mechanisms without threads + game = new Game(players.slice(0, NUM_PLAYERS)); + // + game.start(MS_PER_FRAME); + // + players = players.slice(NUM_PLAYERS); + } +} diff --git a/server/package-lock.json b/server/package-lock.json new file mode 100644 index 0000000..fb88917 --- /dev/null +++ b/server/package-lock.json @@ -0,0 +1,19 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } +} diff --git a/server/player.js b/server/player.js new file mode 100644 index 0000000..0c0767e --- /dev/null +++ b/server/player.js @@ -0,0 +1,34 @@ + + +function Player(ws) { + this.status = 'x'; + this.socket = ws; + this.socket.onmessage = this.listener; +} + +Player.prototype.listener = function(msg) { + var data = msg.data; + if(typeof data == "string" && data.length > 0) { + if(data[0] == 'u') + this.status = 'u'; + else if(data[0] == 'd') + this.status = 'd'; + else + this.status = 'x'; + } +} + +Player.prototype.send_data = function(data) { + if(this.socket.readyState==1) { // TODO: replace the '1' with the proper identifier (the ready state constant) + this.socket.send(data); + } +} + +Player.prototype.get_status = function() { + var stat = this.status; + this.status = 'x'; + return stat; +} + + +module.exports = Player;