#!/usr/bin/python MAXTRANS = 5000 SV_INITS2C = 0 SV_MAPCHANGE = 11 SV_ITEMLIST = 21 PROTOCOL_VERSION = 249 DMF = 16 DVELF = 1 import enet import weakref import packetWrangler from threading import Thread import time class monsterThread(Thread): __stop = False def stop(self): self.__stop = True print "stopping monster actions" def run(self): print "starting monster actions" x = monster() x.name = "Bob" y = monster() y.name = "a mean putty cat" x.o = [2215, 1588, 2320] y.o = [2235, 1588, 2340] while self.__stop == False: text = "monsters lurk about" x.sendInfo() y.sendInfo() send(enet.mint_messagePacket(text)); print text time.sleep(1) connections = {} ents = {} peers = {} class ent: # instantiate entnum to first free integer entry in dictionary for j in range(0, len(ents)+1): if(not ents.has_key(j)): entnum = j break ents[entnum] = self map = "limbo" name = "Unnamed Entity" maxhp = 1 # we need this because its sent by SV_INFO # used to make sure you don't get damage sent to you from your last life lifesequence = 0 peer = enet.ENetPeer() o = [0,0,0] v = [0,0,0] g = [0,0,0] yaw = 0 pitch = 0 roll = 0 physstate = 0 move_pack = 0 def sendUpdate(this): # TODO the 0,0,0 should be g[0]-g[2] but causes a crash pclean = enet.mint_posPacket(this.entnum, this.o[0], this.o[1], this.o[2], this.yaw, this.pitch, this.roll, this.v[0], this.v[1], this.v[2], this.physstate, 0,0,0, this.move_pack); osend(this, pclean) def sendInfo(this): print "sending info for %d" % this.entnum pclean = enet.mint_infoPacket(this.entnum, this.o[0], this.o[1], this.o[2], this.yaw, this.pitch, this.roll, this.v[0], this.v[1], this.v[2], this.physstate, 0,0,0, this.move_pack, this.name, this.lifesequence, this.maxhp); osend(this, pclean); class being(ent): name = "Unnamed Being" hp = 100 maxhp = 100 class player(being): name = "Unnamed Player" class monster(being): name = "Unnamed Monster" def send(packet): for a in connections: enet.enet_peer_send(connections[a].peer, 0, packet); def osend(player, packet): for a in connections: if connections[a] != player and connections[a].map == player.map: enet.enet_peer_send(connections[a].peer, 0, packet); def handleInput(player, packet): pw = packetWrangler.packetWrangler() #for a in enet.IntVector(enet.parsepacket(packet)): print "VECT: %d" % a #print "----- FEEDING ---" pw.feed(enet.IntVector(enet.parsepacket(packet))) while pw.hasData(): # SV_POS, position & movement info type = pw.getInt() if type == 2: #print "POS packet, client num" pw.getInt() # clientnum #print "xyz yaw" player.o[0] = pw.getUint()/DMF # x player.o[1] = pw.getUint()/DMF # y player.o[2] = pw.getUint()/DMF # z player.yaw = pw.getUint() # yaw player.pitch = pw.getInt() # pitch player.roll = pw.getInt() # roll player.v[0] = pw.getInt()/DVELF # velocity x player.v[1] = pw.getInt()/DVELF # velocity y player.v[2] = pw.getInt()/DVELF # velocity z #print "State Info" tmp = pw.getInt() if tmp & 0x10: # physstate pack player.g[0] = pw.getInt()/DVELF # gravity x player.g[1] = pw.getInt()/DVELF # gravity y player.g[2] = pw.getInt()/DVELF # gravity z pw.getInt() # state pack player.sendUpdate(); elif type == 1: # player init info player.name = pw.getStr() pw.getStr() player.lifesequence = pw.getInt() pw.getInt() pw.getInt() player.sendInfo(); #osend(player, packet) elif type == 3: # text from player text = pw.getStr() msg = player.name + ": " + text; print msg osend(player, enet.mint_messagePacket(text)); #print "TEXT FROM PLAYER" #print text #for i in range(3): print player.o[i-1] elif type == 10: # map name pw.getStr() name = pw.getInt() elif type == 14: # ping pw.getInt() elif type == 21: # server message, needs to be here to avoid crashing on forged packet becasue its a fixed length message pw.getStr() elif type == 22: #item list while pw.getInt() != -1: continue elif type == 38: # ctf bases while pw.getInt() != -1: getInt(p) getInt(p) elif type == 39: # ctf base info pw.getInt() pw.getStr() pw.getStr() pw.getInt() elif type == 40: # team score pw.getStr() pw.getInt() else: print "Unknown packet type %d." % type x = enet.msgsize(type) - 1 if(x > 0 & pw.hasData()): if(type < 1): print "We should never get a packet type %d!" % type raise SystemExit for a in range(x): pw.getInt() #print "Recovered, skipped %d integer" % x else: print "Non-fixed packet size, thus non-recoverable." #while pw.hasData(): print pw.getUint() raise SystemExit def sendwelcome(peer, n): packet = enet.mint_welcomePacket(n) enet.enet_peer_send(peer, 0, packet); if(packet.referenceCount==0): enet.enet_packet_destroy(packet); packet = enet.mint_mapChangePacket("legoland") enet.enet_peer_send(peer, 0, packet); if(packet.referenceCount==0): enet.enet_packet_destroy(packet); packet = enet.mint_itemListPacket(); enet.enet_peer_send(peer, 0, packet); if(packet.referenceCount==0): enet.enet_packet_destroy(packet); #start monsters mt = monsterThread() mt.start() if(enet.enet_initialize()<0): print("Unable to initialise network module"); serverAddress = enet.ENetAddress() serverAddress.host = 0 #ENET_HOST_ANY serverAddress.port = 28785 #SAUERBRATEN_SERVER_PORT server = enet.enet_host_create(serverAddress, 32, 0, 0) event = enet.ENetEvent() while(1): enet.enet_host_service(server, event, 1000) if event.type == 1: new_player = player() new_player.peer = event.peer # add to the list of ents ents[new_player.entnum] = new_player connections[event.peer.incomingPeerID] = new_player sendwelcome(event.peer, new_player.entnum) elif event.type == 2: print "Disconnect" del ents[connections[event.peer.incomingPeerID].entnum] del connections[event.peer.incomingPeerID] enet.enet_peer_disconnect(event.peer, 0); elif event.type == 3: handleInput(ents[connections[event.peer.incomingPeerID].entnum], event.packet) #packet = enet.mint_messagePacket("Hello There") #peer = ents[connections[event.peer.incomingPeerID].entnum].peer #enet.enet_peer_send(peer, 0, packet); elif event.type == 10: #ignore map change break; elif event.type == 16: break; time.sleep(.01) enet.enet_deinitialize() mt.stop() mt.join()