def networkKeepAlive(serversocket,clientprops): while 1: if clientprops.gotServLoc == 1: serversocket.sendall(mcpackets.encode("c2s",0x0A,{ 'flying':0, })) serversocket.sendall(mcpackets.encode("c2s",0x0B,{'x':clientprops.playerloc[0], 'y':clientprops.playerloc[1], 'z':clientprops.playerloc[2], 'stance':clientprops.playerloc[1] + 1.62, 'onground':False, })) serversocket.sendall(mcpackets.encode("c2s",0x0C,{ 'rotation':0, 'pitch':0, 'flying':0, })) serversocket.sendall(mcpackets.encode("c2s",0x0D,{'x':clientprops.playerloc[0], 'y':clientprops.playerloc[1], 'z':clientprops.playerloc[2], 'stance':clientprops.playerloc[1] + 1.62, 'rotation':0, 'pitch':0, 'flying':0, })) else: logprint("no pos from server yet: %i\n" % clientprops.gotServLoc) time.sleep(0.05)
def networkThread(serversocket, buff, clientprops): logprint("Started network thread\n") while 1: packetid = struct.unpack("!B", buff.read(1))[0] #if packetid not in [0x1F, 0x21, 0x1C, 0x04, 0x22, 0x18]: #logprint("Got %s\n" % mcpackets.decoders[packetid]["name"]) packet = mcpackets.decode("s2c", buff, packetid) if packetid == 0x33: logprint("test\n") if packetid in [0x33, 0x34, 0x35]: logprint("updated map with 0x%.2x\n" % packetid) minichunktracker.addPacketChanges(packetid, packet, None) drawMap() if packetid == 0x03: message = packet['message'].encode('utf-8') logprint(message+"\n")#,curses.color_pair(curses.COLOR_CYAN)) if packetid in [0x0B, 0x0C, 0x0D]: # spawn pos? clientprops.gotServLoc = 1 logprint("got player position: %f %f %f\n" % (clientprops.playerloc[0],clientprops.playerloc[1],clientprops.playerloc[2])) if packetid in [0x0B,0x0D]: clientprops.playerloc[0] = packet['x'] clientprops.playerloc[1] = packet['y'] clientprops.playerloc[2] = packet['z'] if packetid in [0x0C,0x0D]: clientprops.playerdir = packet['rotation'] clientprops.playerpitch = packet['pitch'] serversocket.sendall(mcpackets.encode("c2s",0x0D,{'x':clientprops.playerloc[0], 'y':clientprops.playerloc[1], 'z':clientprops.playerloc[2], 'stance':clientprops.playerloc[1] + 1.62, 'rotation':0, 'pitch':0, 'flying':0, })) if packetid == 0x06: logprint("got spawn pos") clientprops.playerloc[0] = packet['x'] clientprops.playerloc[1] = packet['y'] clientprops.playerloc[2] = packet['z'] serversocket.sendall(mcpackets.encode("c2s",0x0D,{'x':clientprops.playerloc[0], 'y':clientprops.playerloc[1], 'z':clientprops.playerloc[2], 'stance':clientprops.playerloc[1] + 1.62, 'rotation':0, 'pitch':0, 'flying':0, })) if packetid == 0x32: serversocket.sendall(mcpackets.encode("c2s",0x0D,{'x':clientprops.playerloc[0], 'y':clientprops.playerloc[1], 'z':clientprops.playerloc[2], 'stance':clientprops.playerloc[1] + 1.62, 'rotation':0, 'pitch':0, 'flying':0, }))
def entomb(serverprops, command): import math import time if len(command)==1: print("syntax: entomb with blocks") if len(command) >= 2: try: otherplayer = [id for id,props in serverprops.players.items() if command[1].lower() in props['playerName'].lower()][0] except: print "cannot find player %s" % command[1] return try: block = int(command[1]) except: print "%s is not an integer. cannot make block." % command[2] return their_x = int(math.floor(serverprops.players[otherplayer]['x']/32)) their_y = int(math.floor(serverprops.players[otherplayer]['y']/32)) their_z = int(math.floor(serverprops.players[otherplayer]['z']/32)) for x in xrange(their_x -2, their_x + 2): for y in xrange(their_y -2, their_y + 5): for z in xrange(their_z -2, their_z + 2): if block!=0: packet = {'dir':'c2s', 'itemid':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1, 'amount': 1, 'damage': 0} #direction: +X print packet encpacket = mcpackets.encode('c2s', 0x0F, packet) serverprops.comms.serverqueue.put(encpacket)
def chat(self, *messages, **kwargs): from mcpackets import encode """Use me to give information back to user via in-game chat.""" prefix = settings.chat_prefix for message in messages: for line in message.replace("\r\n").split("\n"): self.comms.clientqueue.put(encode('s2c',0x03, {'message':prefix+line}))
def sock_foward(dir, insocket, outsocket, outqueue, serverprops): buff = FowardingBuffer(insocket, outsocket) try: while True: #decode packet buff.packet_start() packetid = struct.unpack("!B", buff.read(1))[0] if packetid in mcpackets.decoders.keys(): packet = mcpackets.decode(dir, buff, packetid) else: print "unknown packet 0x%2X from" % packetid, {'c2s':'client', 's2c':'server'}[dir] buff.packet_end() continue packetbytes = buff.packet_end() modpacket = run_hooks(packetid, packet, serverprops) if modpacket == None: # if run_hooks returns none, the packet was not modified packet_info(packetid, packet, buff, serverprops) buff.write(packetbytes) else: packet_info(packetid, modpacket, buff, serverprops) buff.write(mcpackets.encode(dir,packetid,modpacket)) #print "changed packet" #packet_info(packetid, modpacket, buff, serverprops) #send all items in the outgoing queue while not outqueue.empty(): task = outqueue.get() buff.write(task) outqueue.task_done() except socket.error, e: print( dir, "connection quit unexpectedly:") print e return
def movespawn(serverprops, command): if len(command) == 4: packet = {'x':int(command[1]), 'y':int(command[2]), 'z':int(command[3])} encpacket = mcpackets.encode("s2c", mcpackets.name_to_id['spawnposition'], packet) serverprops.comms.clientqueue.put(encpacket) print "sent" else: print "Not enough arguments 'movespawn X Y Z' Relative to the map, NOT the player"
def fill(serverprops, command): import math import time if len(command)==1: print("syntax: fill player_at_other_corner blocktype [hollow|nosides]") if len(command) >= 3: try: otherplayer = [id for id,props in serverprops.players.items() if command[1].lower() in props['playerName'].lower()][0] except: print "cannot find player %s" % command[1] return try: block = int(command[2]) except: print "%s is not an integer. cannot make block." % command[2] return my_x = int(math.floor(serverprops.playerdata['location'][0])); their_x = int(math.floor(serverprops.players[otherplayer]['x']/32)) my_y = int(math.floor(serverprops.playerdata['location'][1])); their_y = int(math.floor(serverprops.players[otherplayer]['y']/32)) my_z = int(math.floor(serverprops.playerdata['location'][2])); their_z = int(math.floor(serverprops.players[otherplayer]['z']/32)) if my_x <= their_x: x_range = xrange(my_x, their_x+1) else: x_range = xrange(my_x, their_x-1, -1) if my_y <= their_y: y_range = xrange(my_y, their_y+1) else: y_range = xrange(my_y, their_y-1, -1) if my_z <= their_z: z_range = xrange(my_z, their_z+1) else: z_range = xrange(my_z, their_z-1, -1) for x in x_range: for z in z_range: for y in y_range: # #remove block # packet = {'dir':'c2s', 'status':0, 'x':x, 'y':y, 'z':z, 'direction': 1} #direction: +X # encpacket = mcpackets.encode('c2s', 0x0E, packet) #block dig # serverprops.comms.serverqueue.put(encpacket) # packet = {'dir':'c2s', 'status':1, 'x':x, 'y':y, 'z':z, 'direction': 1} #direction: +X # encpacket = mcpackets.encode('c2s', 0x0E, packet) #block dig # serverprops.comms.serverqueue.put(encpacket) # packet = {'dir':'c2s', 'status':3, 'x':x, 'y':y, 'z':z, 'direction': 1} #direction: +X # encpacket = mcpackets.encode('c2s', 0x0E, packet) #block dig # serverprops.comms.serverqueue.put(encpacket) if block!=0: #place block packet = {'dir':'c2s', 'itemid':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1, 'amount': 1, 'damage': 0} #direction: +X encpacket = mcpackets.encode('c2s', 0x0F, packet) serverprops.comms.serverqueue.put(encpacket)
def Teleport(self): #hooks.addHook(self.serverprops,'overridePlayerPos') wploc = self.serverprops.waypoint[self.serverprops.currentwp] my_x = int(math.floor(self.serverprops.playerdata['location'][0])) my_y = int(math.floor(self.serverprops.playerdata['location'][1])) my_z = int(math.floor(self.serverprops.playerdata['location'][2])) jumpdist = 20 x_reached=False y_reached=False z_reached=False while((x_reached==False) or (y_reached==False) or (z_reached==False)): my_x = int(math.floor(self.serverprops.playerdata['location'][0])) my_y = int(math.floor(self.serverprops.playerdata['location'][1])) my_z = int(math.floor(self.serverprops.playerdata['location'][2])) if (my_x <= wploc[0]) and (x_reached==False): if wploc[0] - my_x > jumpdist: my_x += jumpdist else: my_x = wploc[0]; x_reached = True elif my_x - wploc[0] > jumpdist: my_x -= jumpdist else: my_x = wploc[0]; x_reached = True if (my_y <= wploc[1]) and (y_reached==False): if wploc[1] - my_y > jumpdist: my_y += jumpdist else: my_y = wploc[1]; y_reached = True elif my_y - wploc[1] > jumpdist: my_y -= jumpdist else: my_y = wploc[1] + 4; y_reached = True if (my_z <= wploc[2]) and (z_reached==False): if wploc[2] - my_z > jumpdist: my_z += jumpdist else: my_z = wploc[2]; z_reached = True elif my_z - wploc[2] > jumpdist: my_z -= jumpdist else: my_z = wploc[2]; z_reached = True print("X:%s Y:%s Z:%s to X:%s Y:%s Z:%s %s%s%s" % (my_x, my_y, my_z, wploc[0], wploc[1], wploc[2],x_reached, y_reached, z_reached)) time.sleep(0.05) packet = {'x':my_x, 'y':my_y, 'stance':0, 'z':my_z, 'onground':0} encpacket = mcpackets.encode("s2c",mcpackets.name_to_id['playerposition'],packet) self.serverprops.comms.clientqueue.put(encpacket) hooks.removeHook(self.serverprops,'overridePlayerPos')
def inventory(serverprops, command): if len(command)==1: print("syntax: inventory [add] [blocktype] [ammount] [inventory position]") subcommand = command[1] if subcommand == 'add': try: itemid = int(command[2]) count = int(command[3]) except: print("unknown slot") for slot in hooks.current_inv: if not hooks.current_inv[slot]: hooks.current_inv[slot] = {'itemid': itemid, 'count': count, 'health': 0} packet = {'type':1, 'count':len(hooks.current_inv), 'items':hooks.current_inv} encpacket = mcpackets.encode(mcpackets.name_to_id['inventory'], packet) serverqueue.put(encpacket) clientqueue.put(encpacket) print("added item %i to inventory slot %i" %(itemid, slot)) break if subcommand == 'list': for slot in hooks.current_inv: if hooks.current_inv[slot]: print ("%i: %ix%s" % (slot, hooks.current_inv[slot]['count'], hooks.current_inv[slot]['itemid']))
def chatCommand(packetid, packet, serverprops): if packet['dir'] == 'c2s': if packet['message'].startswith('#'): command = packet['message'][1:].split(" ") commands.runCommand(serverprops,command) return {} elif packet['message'].startswith('/give '): msg = packet['message'].split(" ") item = msg[2] try: itemnum = int(item) except ValueError: if item in items.id2underName: itemnum = items.id2underName[item] elif item in items.item2underName: itemnum = items.item2underName[item] else: print "Unknown item: " + item return {} msg[2] = str(itemnum) if len(msg) == 4: num = msg[3] try: num = int(num) except: print "invalid number" return {} if num > 64: msg[3] = "64" packets = int((num - 64)/64) packet2 = {'message':"/give %s %s 64" % (msg[1],msg[2])} encpacket = mcpackets.encode("c2s",mcpackets.name_to_id['chat'],packet2) for i in range(packets): serverprops.comms.serverqueue.put(encpacket) packet['message'] = " ".join(msg) return packet
def run(self, radius, height, block_type, *args): try: radius = int(radius) height = int(height) except: self.chat("radius and height must be integers") return try: block = items.get_block_type(block_type) except: self.chat("blocktype must be integer or known blocktype string") return print("radius:%s height:%s block:%s" % (radius, height, block)) my_x = int(math.floor(self.server.playerdata['location'][0])); my_y = int(math.floor(self.server.playerdata['location'][1])); my_z = int(math.floor(self.server.playerdata['location'][2])); y_range = xrange(my_y, my_y + height) print(y_range) step = (1.0/radius) print(step) for y in y_range: sep = 0.0 while sep < (2*math.pi): x = round(radius*math.cos(sep) + my_x) z = round(radius*math.sin(sep) + my_z) sep = sep + step print("X:%s Y:%s Z:%s" % (x, y, z)) if block!=0: #place block packet = {'dir':'c2s', 'type':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1} #direction: +X encpacket = mcpackets.encode('c2s', 0x0F, packet) self.comms.serverqueue.put(encpacket)
def tower (serverprops, command): import math import time if len(command)==1: print("syntax: fill player_at_other_corner blocktype [hollow|nosides]") if len(command) >= 4: try: radius = float(command[1]) height = int(command[2]) block = int(command[3]) print("radius:%s height:%s block:%s" % (radius, height, block)) except: print "%s is not an integer. cannot make block." % command[1] return my_x = int(math.floor(serverprops.playerdata['location'][0])); my_y = int(math.floor(serverprops.playerdata['location'][1])); my_z = int(math.floor(serverprops.playerdata['location'][2])); y_range = xrange(my_y, my_y + height) print(y_range) step = (1.0/radius) print(step) for y in y_range: sep = 0.0 while sep < (2*math.pi): x = round(radius*math.cos(sep) + my_x) z = round(radius*math.sin(sep) + my_z) sep = sep + step print("X:%s Y:%s Z:%s" % (x, y, z)) if block!=0: #place block packet = {'dir':'c2s', 'itemid':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1, 'amount': 1, 'damage': 0} #direction: +X encpacket = mcpackets.encode('c2s', 0x0F, packet) serverprops.comms.serverqueue.put(encpacket)
def entombme (serverprops, command): import math import time if len(command)==1: print("syntax: fill player_at_other_corner blocktype [hollow|nosides]") if len(command) >= 2: try: block = int(command[1]) except: print "%s is not an integer. cannot make entomb." % command[1] return my_x = int(math.floor(serverprops.playerdata['location'][0])); my_y = int(math.floor(serverprops.playerdata['location'][1])); my_z = int(math.floor(serverprops.playerdata['location'][2])); for x in xrange(my_x -2, my_x + 3): for y in xrange(my_y -2, my_y + 4): for z in xrange(my_z -2, my_z + 3): if block!=0: #place block packet = {'dir':'c2s', 'itemid':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1, 'amount': 20, 'damage': 0} #direction: +X encpacket = mcpackets.encode('c2s', 0x0F, packet) serverprops.comms.serverqueue.put(encpacket)
def addtoinv(serverprops, command): if len(command) == 1: print "addtoinv [itemID|itemName] [quantity]" if (len(command) == 2) or (len(command) == 3): if len(command) == 2: amount = 1 else: amount = int(command[2]) haveitem = 0 try: itemtype = int(command[1]) haveitem = 1 except ValueError: if command[1] in items.id2underName: itemtype = items.id2underName[command[1]] haveitem = 1 if command[1] in items.item2underName: itemtype = items.item2underName[command[1]] haveitem = 1 else: print "Unknown item" if haveitem: packet = { 'itemtype': itemtype, 'amount': amount, 'life': 0} serverprops.comms.clientqueue.put(mcpackets.encode("s2c",mcpackets.name_to_id['addtoinv'],packet))
def testchat(serverprops, command): packet = { 'message': 'lol'} encpacket = mcpackets.encode("s2c",mcpackets.name_to_id['chat'],packet) serverprops.comms.clientqueue.put(encpacket) print "packet sent"
class clientprops(): gotServLoc = 0 playerloc = [0,0,0] playerdir = 0 playerpitch = 0 session = MCLogin() logprint("Connecting to server... ") serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) serversocket.connect(("stackunderflow.com",25555)) buff = serversocket.makefile('rb', 4096) logprint("Success\n") logprint("Sending handshake... ") serversocket.sendall(mcpackets.encode("c2s",0x02,{'username':session[0]})) logprint("Waiting for response... ") packetid = struct.unpack("!B", buff.read(1))[0] #logprint("Got %s\n" % mcpackets.decoders[packetid]["name"]) if packetid == 0x02: packet = mcpackets.decode("s2c", buff, packetid) connhash = packet['username'] logprint("Got conn hash: %s\n" % connhash) else: logprint("Error: expected 0x01, got 0x%x" % packetid) MCServerAuth(session,connhash) logprint("Sending login... ") serversocket.sendall(mcpackets.encode("c2s",0x01,{'protoversion':14, 'username':session[0], 'seed':0, 'dimension':0}))
def compassWayPoint(self): wploc = self.serverprops.waypoint[self.serverprops.currentwp] packet = {'x':wploc[0], 'y':wploc[1], 'z':wploc[2]} encpacket = mcpackets.encode("s2c", mcpackets.name_to_id['spawnposition'], packet) self.serverprops.comms.clientqueue.put(encpacket)
def Teleport(self): wploc = self.serverprops.waypoint[self.serverprops.currentwp] packet = {'x':wploc[0], 'y':wploc[1]+5, 'stance':0, 'z':wploc[2], 'rotation':0, 'pitch':0, 'flying':0} encpacket = mcpackets.encode("s2c",mcpackets.name_to_id['playermovelook'],packet) self.serverprops.comms.clientqueue.put(encpacket)
def circle (serverprops, command): import math import time if len(command)==1: print("syntax: fill player_at_other_corner blocktype [hollow|nosides]") if len(command) >= 4: try: radius = float(command[1]) height = int(command[2]) slope = float(command[3]) thickness = int(command[4]) block = int(command[5]) print("radius: %s height: %s block: %s" % (radius, height, block)) except: return my_x = int(math.floor(serverprops.playerdata['location'][0])); my_y = int(math.floor(serverprops.playerdata['location'][1])); my_z = int(math.floor(serverprops.playerdata['location'][2])); if (height > 0): y_range = xrange(my_y, my_y + height) else: y_range = xrange(my_y-1, my_y + height -1, -1) print(y_range) for y in y_range: radius = (radius + slope) thickness_radius = radius - thickness -1 for t in range(-thickness , thickness+1): thickness_radius = thickness_radius + 1 print("Radius: %s ThckR: %s" % (radius, thickness_radius)) f = 1 - thickness_radius ddF_x = 1 ddF_y = -2 * thickness_radius circle_x = 0 circle_y = thickness_radius xy = range(0, 17) xy[0] = my_x; xy[1] = my_z + thickness_radius xy[2] = my_x; xy[3] = my_z - thickness_radius xy[4] = my_x + thickness_radius; xy[5] = my_z xy[6] = my_x - thickness_radius; xy[7] = my_z i=0 for i in range(0,7): x = xy[i]; z = xy[i+1] #print("X:%s Y:%s Z:%s" % (x, y, z)) if block!=0: #place block packet = {'dir':'c2s', 'type':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1} #direction: +X encpacket = mcpackets.encode('c2s', 0x0F, packet) serverprops.comms.serverqueue.put(encpacket) while(circle_x < circle_y): #ddF_x == 2 * x + 1; #ddF_y == -2 * y; #f == x*x + y*y - radius*radius + 2*x - y + 1; if(f >= 0): circle_y -= 1 ddF_y += 2 f += ddF_y circle_x += 1 ddF_x += 2 f += ddF_x xy[0] = my_x + circle_x; xy[1] = my_z + circle_y #these are the octant of the circle to have geometry remain consistent on larger scales (rounding errors occur) xy[2] = my_x - circle_x; xy[3] = my_z + circle_y xy[4] = my_x + circle_x; xy[5] = my_z - circle_y xy[6] = my_x - circle_x; xy[7] = my_z - circle_y xy[8] = my_x + circle_y; xy[9] = my_z + circle_x xy[10] = my_x - circle_y; xy[11] = my_z + circle_x xy[12] = my_x + circle_y; xy[13] = my_z - circle_x xy[14] = my_x - circle_y; xy[15] = my_z - circle_x i=0 for i in range(0, 15): x = xy[i]; z = xy[i+1] #print("X:%s Y:%s Z:%s" % (x, y, z)) if block!=0: #place block packet = {'dir':'c2s', 'itemid':block, 'x':x, 'y':y-1, 'z':z, 'direction': 1, 'amount': 1, 'damage': 0} #direction: +X encpacket = mcpackets.encode('c2s', 0x0F, packet) serverprops.comms.serverqueue.put(encpacket)
def setslot(serverprops,command): slot = int(command[1]) btype = int(command[2]) packet = { 'itemid': btype, 'slotid': slot, 'windowid': 0, 'itemcount': 1, 'itemuses': 0} serverprops.comms.clientqueue.put(mcpackets.encode("s2c",mcpackets.name_to_id['setslot'],packet))
def printToPlayer(serverprops,message): packet = {'message':message} encpacket = mcpackets.encode("s2c",mcpackets.name_to_id['chat'],packet) serverprops.comms.clientqueue.put(encpacket)
def print_chat(self, message): """Use me to give information back to user via in-game chat.""" prefix = getattr(self._local.server, 'chat_prefix', DEFAULT_MESSAGE_PREFIX) for line in message.replace("\r\n","\n").split("\n"): self._local.comms.clientqueue.put(mcpackets.encode('s2c',0x03, {'message':prefix+line}))
def testpos(serverprops, command): packet = {'x':173, 'y':70, 'stance':0, 'z':544, 'rotation':0, 'pitch':0, 'flying':0} encpacket = mcpackets.encode("s2c",mcpackets.name_to_id['playermovelook'],packet) serverprops.comms.clientqueue.put(encpacket) print "sent"