def dequeue_packet(self): with self.lock: packetid, packet = self.world.sector_packets.popleft() if packetid == 1: # Sector blocks, sectors = self.world, self.world.sectors secpos = struct.unpack("iii", packet[:12]) sector = sectors[secpos] cx, cy, cz = sector_to_blockpos(secpos) fpos = 12 exposed_pos = fpos + 1024 for x in xrange(cx, cx+8): for y in xrange(cy, cy+8): for z in xrange(cz, cz+8): read = packet[fpos:fpos+2] fpos += 2 unpacked = structuchar2.unpack(read) if read != null2 and unpacked in BLOCKS_DIR: position = x,y,z blocks[position] = BLOCKS_DIR[unpacked] sector.append(position) if packet[exposed_pos] is "1": blocks.show_block(position) exposed_pos += 1 if secpos in self.world.sector_queue: del self.world.sector_queue[secpos] #Delete any hide sector orders elif packetid == 2: # Blank Sector self.world.sectors[packet] = [] elif packetid == 3: # Add Block self.world._add_block(packet[0], packet[1]) elif packetid == 4: # Remove Block self.world._remove_block(packet) elif packetid == 5: # Chat Print self.controller.write_line(packet[0], color=packet[1]) if not self.controller.text_input.visible: self.controller.chat_box.visible = True pyglet.clock.unschedule(self.controller.hide_chat_box) pyglet.clock.schedule_once(self.controller.hide_chat_box, G.CHAT_FADE_TIME) elif packetid == 6: # Inventory player = self.controller.player caret = 0 for inventory in (player.quick_slots.slots, player.inventory.slots, player.armor.slots): for i in xrange(len(inventory)): id_main, id_sub, amount = struct.unpack("HBB", packet[caret:caret+4]) caret += 4 if id_main == 0: continue durability = -1 if id_main >= G.ITEM_ID_MIN and (id_main, id_sub) not in G.ITEMS_DIR: #The subid must be durability durability = id_sub * G.ITEMS_DIR[(id_main, 0)].max_durability / 255 id_sub = 0 inventory[i] = ItemStack(type=BlockID(id_main, id_sub), amount=amount, durability=durability) self.controller.item_list.update_items() self.controller.inventory_list.update_items() elif packetid == 7: print(packet) elif packetid == 255: # Spawn Position self.controller.player.position = packet #Now that we know where the player should be, we can enable .update again self.controller.update = self.controller.update_disabled
def get_exposed_sector(self, sector: iVector) -> bytes: """ Returns a 512 length string of 0's and 1's if blocks are exposed """ cx, cy, cz = savingsystem.sector_to_blockpos(sector) # Most ridiculous list comprehension ever, but this is 25% faster than using appends return b"".join([(x, y, z) in self and self.is_exposed( (x, y, z)) and b"1" or b"0" for x in range(cx, cx + 8) for y in range(cy, cy + 8) for z in range(cz, cz + 8)])
def get_exposed_sector_cached(self, sector): """ Cached. Returns a 512 length string of 0's and 1's if blocks are exposed """ if sector in self.exposed_cache: return self.exposed_cache[sector] cx,cy,cz = sector_to_blockpos(sector) #Most ridiculous list comprehension ever, but this is 25% faster than using appends self.exposed_cache[sector] = "".join([(x,y,z) in self and self.is_exposed((x,y,z)) and "1" or "0" for x in xrange(cx, cx+8) for y in xrange(cy, cy+8) for z in xrange(cz, cz+8)]) return self.exposed_cache[sector]
def get_exposed_sector(self, sector): """ Returns a 512 length string of 0's and 1's if blocks are exposed """ cx, cy, cz = sector_to_blockpos(sector) #Most ridiculous list comprehension ever, but this is 25% faster than using appends # return "".join([(x,y,z) in self and self.is_exposed((x,y,z)) and "1" or "0" # for x in range(cx, cx+8) for y in range(cy, cy+8) for z in range(cz, cz+8)]) return "".join([ str(int(((x, y, z) in self) and (self.is_exposed((x, y, z))))) for x in range(cx, cx + 8) for y in range(cy, cy + 8) for z in range(cz, cz + 8) ])
def open_sector(self, sector: iVector): # The sector is not in memory, load or create it if savingsystem.sector_exists(sector): # If its on disk, load it savingsystem.load_region(self, sector=sector) else: # The sector doesn't exist yet, generate it! bx, by, bz = savingsystem.sector_to_blockpos(sector) rx, ry, rz = bx // 32 * 32, by // 32 * 32, bz // 32 * 32 # For ease of saving/loading, queue up generation of a whole region (4x4x4 sectors) at once yiter, ziter = range(ry // 8, ry // 8 + 4), range(rz // 8, rz // 8 + 4) for secx in range(rx // 8, rx // 8 + 4): for secy in yiter: for secz in ziter: self.terraingen.generate_sector((secx, secy, secz))
def dequeue_packet(self): with self.lock: packetid, packet = self.world.sector_packets.popleft() if packetid == 1: # Sector blocks, sectors = self.world, self.world.sectors secpos = struct.unpack("iii", packet[:12]) sector = sectors[secpos] cx, cy, cz = sector_to_blockpos(secpos) fpos = 12 exposed_pos = fpos + 1024 for x in xrange(cx, cx+8): for y in xrange(cy, cy+8): for z in xrange(cz, cz+8): read = packet[fpos:fpos+2] fpos += 2 unpacked = structuchar2.unpack(read) if read != null2 and unpacked in BLOCKS_DIR: position = x,y,z blocks[position] = BLOCKS_DIR[unpacked] sector.append(position) if packet[exposed_pos] is "1": blocks.show_block(position) exposed_pos += 1 if secpos in self.world.sector_queue: del self.world.sector_queue[secpos] #Delete any hide sector orders elif packetid == 2: # Blank Sector self.world.sectors[packet] = [] elif packetid == 3: # Add Block self.world._add_block(packet[0], packet[1]) elif packetid == 4: # Remove Block self.world._remove_block(packet) elif packetid == 5: # Chat Print self.controller.write_line(packet[0], color=packet[1]) elif packetid == 255: # Spawn Position self.controller.player.position = packet #Now that we know where the player should be, we can enable .update again self.controller.update = self.controller.update_disabled
def dequeue_packet(self): with self.lock: packetid, packet = self.world.sector_packets.popleft() if packetid == 1: # Entire Sector blocks, sectors = self.world, self.world.sectors secpos = struct.unpack("iii", packet[:12]) sector = sectors[secpos] cx, cy, cz = sector_to_blockpos(secpos) fpos = 12 exposed_pos = fpos + 1024 for x in range(cx, cx + 8): for y in range(cy, cy + 8): for z in range(cz, cz + 8): read = packet[fpos:fpos + 2] fpos += 2 unpacked = structuchar2.unpack(read) if read != null2 and unpacked in BLOCKS_DIR: position = x, y, z try: blocks[position] = BLOCKS_DIR[unpacked] if blocks[position].sub_id_as_metadata: blocks[position] = type( BLOCKS_DIR[unpacked])() blocks[position].set_metadata(0) except KeyError: main_blk = BLOCKS_DIR[(unpacked[0], 0)] if main_blk.sub_id_as_metadata: # sub id is metadata blocks[position] = type(main_blk)() blocks[position].set_metadata(unpacked[-1]) sector.append(position) if packet[exposed_pos:exposed_pos + 1] == b"1": blocks.show_block(position) exposed_pos += 1 if secpos in self.world.sector_queue: del self.world.sector_queue[ secpos] #Delete any hide sector orders elif packetid == 2: # Blank Sector self.world.sectors[struct.unpack("iii", packet)] = [] elif packetid == 3: # Add Block self.world._add_block(struct.unpack("iii", packet[:12]), BLOCKS_DIR[struct.unpack("BB", packet[12:])]) elif packetid == 4: # Remove Block self.world._remove_block(struct.unpack("iii", packet)) elif packetid == 5: # Chat Print self.controller.write_line(packet[:-4].decode('utf-8'), color=struct.unpack( "BBBB", packet[-4:])) if not self.controller.text_input.visible: self.controller.chat_box.visible = True pyglet.clock.unschedule(self.controller.hide_chat_box) pyglet.clock.schedule_once(self.controller.hide_chat_box, G.CHAT_FADE_TIME) elif packetid == 6: # Inventory player = self.controller.player caret = 0 for inventory in (player.quick_slots.slots, player.inventory.slots, player.armor.slots): for i in range(len(inventory)): id_main, id_sub, amount = struct.unpack( "HBB", packet[caret:caret + 4]) caret += 4 if id_main == 0: continue durability = -1 if id_main >= G.ITEM_ID_MIN and ( id_main, id_sub) not in G.ITEMS_DIR: #The subid must be durability durability = id_sub * G.ITEMS_DIR[ (id_main, 0)].durability // 255 id_sub = 0 inventory[i] = ItemStack(type=BlockID(id_main, id_sub), amount=amount, durability=durability) self.controller.item_list.update_items() self.controller.inventory_list.update_items() elif packetid == 7: # New player connected plyid, name = struct.unpack( "H", packet[:2])[0], packet[2:].decode('utf-8') if plyid not in self.controller.player_ids: self.controller.player_ids[plyid] = Player(username=name, local_player=False) elif name == '\0': del self.controller.player_ids[plyid] elif packetid == 8: # Player Movement ply = self.controller.player_ids[struct.unpack("H", packet[:2])[0]] ply.momentum = struct.unpack("fff", packet[2:14]) ply.position = struct.unpack("ddd", packet[14:]) elif packetid == 9: # Player Jump self.controller.player_ids[struct.unpack("H", packet)[0]].dy = 0.016 elif packetid == 10: # Update Tile Entity self.world[struct.unpack("iii", packet[:12])].update_tile_entity( packet[12:]) elif packetid == 255: # Spawn Position self.controller.player.position = struct.unpack("iii", packet[:12]) packet = packet[12:] packet, seed = extract_string_packet(packet) self.world.biome_generator = BiomeGenerator(seed) #Now that we know where the player should be, we can enable .update again self.controller.update = self.controller.update_disabled else: warn( "Received unknown packetid %s, there's probably a version mismatch between client and server!" % packetid)
def dequeue_packet(self): with self.lock: packetid, packet = self.world.sector_packets.popleft() # print(f"CLIENTPACKET_ID: ", packetid) if packetid != 1 else None # print(f"CLIENTPACKET_PAK:", packet) if packetid != 1 else None if packetid == 1: # Entire Sector blocks, sectors = self.world, self.world.sectors # secpos = struct.unpack("iii", packet[:12]) secpos = packet["sector"] # print(packet) sector = sectors[secpos] cx, cy, cz = sector_to_blockpos(secpos) fpos = 0 # 12 exposed_pos = 0 # fpos + 1024 for x in range(cx, cx + 8): for y in range(cy, cy + 8): for z in range(cz, cz + 8): sector_data = packet["sectorData"][ fpos:fpos + 2] # .encode("ascii") # print(read) fpos += 2 unpacked = structuchar2.unpack(sector_data) # unpacked = read # print("UNPACKED:", unpacked) if sector_data != null2 and unpacked in BLOCKS_DIR: position = x, y, z try: blocks[position] = BLOCKS_DIR[unpacked] if blocks[position].sub_id_as_metadata: blocks[position] = type( BLOCKS_DIR[unpacked])() blocks[position].set_metadata(0) except KeyError: main_blk = BLOCKS_DIR[(unpacked[0], 0)] if main_blk.sub_id_as_metadata: # sub id is metadata blocks[position] = type(main_blk)() blocks[position].set_metadata(unpacked[-1]) sector.append(position) if packet["exposedSector"][exposed_pos] is "1": blocks.show_block(position) exposed_pos += 1 if secpos in self.world.sector_queue: del self.world.sector_queue[ secpos] # Delete any hide sector orders elif packetid == 2: # Blank Sector self.world.sectors[packet["sector"]] = [] elif packetid == 3: # Add Block self.world._add_block(packet["position"], BLOCKS_DIR[packet["block"]]) elif packetid == 4: # Remove Block self.world._remove_block(packet["position"]) elif packetid == 5: # Chat Print self.controller.write_line(packet["message"].decode('utf-8'), color=packet["color"]) if not self.controller.text_input.visible: self.controller.chat_box.visible = True pyglet.clock.unschedule(self.controller.hide_chat_box) pyglet.clock.schedule_once(self.controller.hide_chat_box, G.CHAT_FADE_TIME) elif packetid == 6: # Inventory player = self.controller.player caret = 0 print("CLIENT_PACKET06:", packet) for i in range(len(player.quick_slots.slots)): id_main, id_sub, amount = packet["items"]["quickSlots"][i] # print(id_main, id_sub, amount) # caret += 4 if id_main == 0: continue durability = -1 if id_main >= G.ITEM_ID_MIN and (id_main, id_sub) not in G.ITEMS_DIR: # The subid must be durability durability = id_sub * G.ITEMS_DIR[BlockID( id_main, 0)].durability / 255 id_sub = 0 player.quick_slots.slots[i] = ItemStack(type=BlockID( id_main, id_sub), amount=amount, durability=durability) for i in range(len(player.inventory.slots)): id_main, id_sub, amount = packet["items"]["inventory"][i] # print(id_main, id_sub, amount) # caret += 4 if id_main == 0: continue durability = -1 if id_main >= G.ITEM_ID_MIN and (id_main, id_sub) not in G.ITEMS_DIR: # The subid must be durability durability = id_sub * G.ITEMS_DIR[BlockID( id_main, 0)].durability / 255 id_sub = 0 player.quick_slots.slots[i] = ItemStack(type=BlockID( id_main, id_sub), amount=amount, durability=durability) for i in range(len(player.armor.slots)): id_main, id_sub, amount = packet["items"]["armor"][i] # print(id_main, id_sub, amount) # caret += 4 if id_main == 0: continue durability = -1 if id_main >= G.ITEM_ID_MIN and (id_main, id_sub) not in G.ITEMS_DIR: # The subid must be durability durability = id_sub * G.ITEMS_DIR[BlockID( id_main, 0)].durability / 255 id_sub = 0 player.quick_slots.slots[i] = ItemStack(type=BlockID( id_main, id_sub), amount=amount, durability=durability) # for inventory in (player.quick_slots.slots, player.inventory.slots, player.armor.slots): # # for item in (player.quick_slots.slots + player.inventory.slots + player.armor.slots) # for i in range(len(inventory)): # # print(packet) # # # print("PACKET_0x06:", packet.decode()) # # # packet = eval(packet.decode()[:-1]) if packet.decode().startswith( # # "b'") and packet.decode().endswith("'" + chr(packet[-1])) else packet # id_main, id_sub, amount = packet[] # # # print(id_main, id_sub, amount) # caret += 4 # if id_main == 0: continue # durability = -1 # if id_main >= G.ITEM_ID_MIN and (id_main, id_sub) not in G.ITEMS_DIR: # # The subid must be durability # durability = id_sub * G.ITEMS_DIR[BlockID(id_main, 0)].durability / 255 # id_sub = 0 # inventory[i] = ItemStack(type=BlockID(id_main, id_sub), amount=amount, durability=durability) self.controller.item_list.update_items() self.controller.inventory_list.update_items() elif packetid == 7: # New player connected # plyid, name = struct.unpack("H", packet[:2])[0], packet[2:].decode('utf-8') plyid = packet["playerID"] name = packet["username"] if plyid not in self.controller.player_ids: self.controller.player_ids[plyid] = Player(username=name, local_player=False) elif name == '\0': del self.controller.player_ids[plyid] elif packetid == 8: # Player Movement ply = self.controller.player_ids[ packet["playerID"]] # struct.unpack("H", packet[:2])[0]] ply.momentum = packet[ "momentum"] # struct.unpack("fff", packet[2:14]) ply.position = packet[ "position"] # struct.unpack("ddd", packet[14:]) elif packetid == 9: # Player Jump self.controller.player_ids[packet["playerID"]].dy = 0.016 elif packetid == 10: # Update Tile Entity self.world[packet["position"]].update_tile_entity(packet["value"]) elif packetid == 255: # Spawn Position self.controller.player.position = packet[ "position"] # struct.unpack("iii", packet[:12]) # print(packet) # packet = packet[12:] # TODO: Get the packet data from dictionary. PACKETID: 255 | CLIENT # packet, seed = extract_string_packet(packet) seed = packet["seed"] self.world.biome_generator = BiomeGenerator(seed) # Now that we know where the player should be, we can enable .update again self.controller.update = self.controller.update_disabled else: warn( "Received unknown packetid %s, there's probably a version mismatch between client and server!" % packetid)
def generate_sector(self, sector): world = self.world if sector in world.sectors: # This sector is already loaded? Does it just have leaf blocks or something? for pos in world.sectors[sector]: if world[pos] not in self.autogenerated_blocks: return #if G.TERRAIN_CHOICE != 'nether': TERRAIN_CHOICE = self.biome_generator.get_biome_type(sector[0], sector[2]) TREE_CHANCE = G.TREE_CHANCE WILDFOOD_CHANCE = G.WILDFOOD_CHANCE GRASS_CHANCE = G.GRASS_CHANCE #TODO: This is very untidy, should be converted to a dict or something clever if TERRAIN_CHOICE == G.FOREST: main_block = grass_block self.height_range = 32 self.height_base = 32 self.island_shore = 0 self.water_level = 35 self.zoom_level = 0.002 TREE_CHANCE = 0.012 elif TERRAIN_CHOICE == G.PLAINS: main_block = grass_block self.height_range = 32 self.height_base = 32 self.island_shore = 0 self.water_level = 0 self.zoom_level = 0.002 TREE_CHANCE = 0.004 elif TERRAIN_CHOICE == G.SNOW: main_block = snowgrass_block self.height_range = 32 self.height_base = 32 self.island_shore = 34 self.water_level = 34 self.zoom_level = 0.002 elif TERRAIN_CHOICE == G.DESERT: main_block = sand_block self.height_range = 32 self.height_base = 32 self.island_shore = 32 self.water_level = 0 self.zoom_level = 0.002 TREE_CHANCE = 0.0002 elif TERRAIN_CHOICE == G.ISLAND: #Does not naturally occur # Some grass that cant be on sand, for a clean beach self.world_type_grass = (YFlowers, Rose, TallGrass) main_block = grass_block self.height_range = 32 self.height_base = 32 self.island_shore = 38 self.water_level = 36 self.zoom_level = 0.002 elif TERRAIN_CHOICE == G.MOUNTAINS: main_block = stone_block self.height_range = 32 self.height_base = 32 self.island_shore = 18 self.water_level = 36 self.zoom_level = 0.001 elif TERRAIN_CHOICE == G.NETHER: #Does not naturally occur main_block = nether_block self.height_range = 32 self.height_base = 32 #no water in the nether self.island_shore = -1 self.water_level = -2 self.zoom_level = 0.01 world.sectors[sector] = [] # Precache it incase it ends up being solid air, so it doesn't get regenerated # indefinitely bx, by, bz = savingsystem.sector_to_blockpos(sector) if 0 <= by < (self.height_base + self.height_range): self.rand.seed(str(self.seed) + "(%d,%d,%d)" % (bx, by, bz)) bytop = by + 8 # We pass these as local variables for performance and readability. # Functions: init_block = world.init_block get_height = self.get_height choose = self.rand.choice rand_random = self.rand.random # Variables (that are static during what follows) height_base = self.height_base island_shore = self.island_shore water_level = self.water_level underwater_blocks = self.underwater_blocks world_type_trees = self.world_type_trees world_type_plants = self.world_type_plants world_type_grass = self.world_type_grass if TERRAIN_CHOICE == G.NETHER: highlevel_ores = ((nether_block,) * 60 + (soulsand_block,) * 35 + (netherore_block,) * 5 + (air_block,) * 10) midlevel_ores = highlevel_ores lowlevel_ores = highlevel_ores else: highlevel_ores = self.highlevel_ores midlevel_ores = self.midlevel_ores lowlevel_ores = self.lowlevel_ores for x in range(bx, bx + 8): for z in range(bz, bz + 8): if by < height_base: # For sectors outside of the height_range, no point checking the heightmap y = height_base else: # The heightmap falls within our sector, generate surface stuff y = get_height(x, z) if y > bytop: y = bytop if TERRAIN_CHOICE == G.MOUNTAINS: if 0 <= y <= 35: # bottom level = grass main_block = grass_block if 36 <= y <= 54: # mid level = rock main_block = stone_block if y >= 55: # top level = snow main_block = snow_block if y <= water_level: if TERRAIN_CHOICE != G.DESERT: # was y == self.height_base -- you can have water! if TERRAIN_CHOICE == G.SNOW: # top block is ice init_block((x, water_level, z), ice_block) else: init_block((x, water_level, z), water_block) # init_block((x, y -1, z), water_block) init_block((x, water_level - 2, z), choose(underwater_blocks)) init_block((x, water_level - 3, z), dirt_block) else: # no water for you! init_block((x, y + 1, z), sand_block) init_block((x, y, z), sand_block) init_block((x, y - 1, z), sand_block) init_block((x, y - 2, z), sandstone_block) init_block((x, y - 3, z), sandstone_block) y -= 3 elif y < bytop: if TERRAIN_CHOICE == G.ISLAND: # always sand by the water, grass above if y > island_shore: main_block = grass_block else: main_block = sand_block init_block((x, y, z), main_block) veget_choice = rand_random() veget_blocks = None if veget_choice < TREE_CHANCE: veget_blocks = world_type_trees elif veget_choice < WILDFOOD_CHANCE: veget_blocks = world_type_plants elif veget_choice < GRASS_CHANCE: veget_blocks = world_type_grass if veget_blocks is not None: world.generate_vegetation((x, y + 1, z), choose(veget_blocks)) if main_block == sand_block: underground_blocks = ( sand_block, sand_block, sandstone_block) elif main_block == stone_block: underground_blocks = (stone_block,) * 3 elif main_block == nether_block: underground_blocks = self.nether else: underground_blocks = (dirt_block,) * 3 for d, block in enumerate(underground_blocks, start=1): init_block((x, y - d, z), block) y -= 3 for yy in range(by, y): # ores and filler... if yy >= 32: blockset = highlevel_ores elif yy > 9: blockset = midlevel_ores elif yy > 2: blockset = lowlevel_ores elif yy <= 1: blockset = (bedrock_block, ) init_block((x, yy, z), choose(blockset))
def generate_sector(self, sector): world = self.world if sector in world.sectors: #This sector is already loaded? Does it just have leaf blocks or something? for pos in world.sectors[sector]: if world[pos] not in self.autogenerated_blocks: return #if G.TERRAIN_CHOICE != 'nether': TERRAIN_CHOICE = self.biome_generator.get_biome_type(sector[0], sector[2]) TREE_CHANCE = G.TREE_CHANCE WILDFOOD_CHANCE = G.WILDFOOD_CHANCE GRASS_CHANCE = G.GRASS_CHANCE #TODO: This is very untidy, should be converted to a dict or something clever if TERRAIN_CHOICE == G.FOREST: main_block = grass_block self.height_range = 32 self.height_base = 32 self.island_shore = 0 self.water_level = 0 self.zoom_level = 0.002 TREE_CHANCE = 0.012 elif TERRAIN_CHOICE == G.PLAINS: main_block = grass_block self.height_range = 32 self.height_base = 32 self.island_shore = 0 self.water_level = 0 self.zoom_level = 0.002 TREE_CHANCE = 0.004 elif TERRAIN_CHOICE == G.SNOW: main_block = snowgrass_block self.height_range = 32 self.height_base = 32 self.island_shore = 34 self.water_level = 33 self.zoom_level = 0.002 elif TERRAIN_CHOICE == G.DESERT: main_block = sand_block self.height_range = 32 self.height_base = 32 self.island_shore = 32 self.water_level = 0 self.zoom_level = 0.002 TREE_CHANCE = 0 elif TERRAIN_CHOICE == G.ISLAND: #Does not naturally occur # Some grass that cant be on sand, for a clean beach self.world_type_grass = (YFlowers, Rose, TallGrass) main_block = grass_block self.height_range = 32 self.height_base = 32 self.island_shore = 38 self.water_level = 36 self.zoom_level = 0.002 elif TERRAIN_CHOICE == G.MOUNTAINS: main_block = stone_block self.height_range = 32 self.height_base = 32 self.island_shore = 18 self.water_level = 20 self.zoom_level = 0.001 elif TERRAIN_CHOICE == G.NETHER: #Does not naturally occur main_block = nether_block self.height_range = 32 self.height_base = 32 #no water in the nether self.island_shore = -1 self.water_level = -2 self.zoom_level = 0.01 world.sectors[sector] = [] # Precache it incase it ends up being solid air, so it doesn't get regenerated indefinitely bx, by, bz = savingsystem.sector_to_blockpos(sector) if 0 <= by < (self.height_base + self.height_range): self.rand.seed(self.seed + "(%d,%d,%d)" % (bx, by, bz)) bytop = by + 8 # We pass these as local variables for performance and readability. # Functions: init_block = world.init_block get_height = self.get_height choose = self.rand.choice rand_random = self.rand.random # Variables (that are static during what follows) height_base = self.height_base island_shore = self.island_shore water_level = self.water_level underwater_blocks = self.underwater_blocks world_type_trees = self.world_type_trees world_type_plants = self.world_type_plants world_type_grass = self.world_type_grass if TERRAIN_CHOICE == G.NETHER: highlevel_ores = ((nether_block,) * 60 + (soulsand_block,) * 35 + (netherore_block,) * 5 + (air_block,) * 10) midlevel_ores = highlevel_ores lowlevel_ores = highlevel_ores else: highlevel_ores = self.highlevel_ores midlevel_ores = self.midlevel_ores lowlevel_ores = self.lowlevel_ores for x in range(bx, bx + 8): for z in range(bz, bz + 8): if by < height_base: # For sectors outside of the height_range, no point checking the heightmap y = height_base else: # The heightmap falls within our sector, generate surface stuff y = get_height(x, z) if y > bytop: y = bytop if TERRAIN_CHOICE == G.MOUNTAINS: if 0 <= y <= 35: # bottom level = grass main_block = grass_block if 36 <= y <= 54: # mid level = rock main_block = stone_block if y >= 55: # top level = snow main_block = snow_block if y <= water_level: if TERRAIN_CHOICE != G.DESERT: # was y == self.height_base -- you can have water! if TERRAIN_CHOICE == G.SNOW: # top block is ice init_block((x, water_level, z), ice_block) else: init_block((x, water_level, z), water_block) # init_block((x, y -1, z), water_block) init_block((x, water_level - 2, z), choose(underwater_blocks)) init_block((x, water_level - 3, z), dirt_block) else: # no water for you! init_block((x, y + 1, z), sand_block) init_block((x, y, z), sand_block) init_block((x, y - 1, z), sand_block) init_block((x, y - 2, z), sandstone_block) init_block((x, y - 3, z), sandstone_block) y -= 3 elif y < bytop: if TERRAIN_CHOICE == G.ISLAND: # always sand by the water, grass above if y > island_shore: main_block = grass_block else: main_block = sand_block init_block((x, y, z), main_block) veget_choice = rand_random() veget_blocks = None if veget_choice < TREE_CHANCE: veget_blocks = world_type_trees elif veget_choice < WILDFOOD_CHANCE: veget_blocks = world_type_plants elif veget_choice < GRASS_CHANCE: veget_blocks = world_type_grass if veget_blocks is not None: world.generate_vegetation((x, y + 1, z), choose(veget_blocks)) if main_block == sand_block: underground_blocks = ( sand_block, sand_block, sandstone_block) elif main_block == stone_block: underground_blocks = (stone_block,) * 3 elif main_block == nether_block: underground_blocks = self.nether else: underground_blocks = (dirt_block,) * 3 for d, block in enumerate(underground_blocks, start=1): init_block((x, y - d, z), block) y -= 3 for yy in range(by, y): # ores and filler... if yy >= 32: blockset = highlevel_ores elif yy > 9: blockset = midlevel_ores elif yy > 2: blockset = lowlevel_ores elif yy <= 1: blockset = (bedrock_block, ) init_block((x, yy, z), choose(blockset))
def dequeue_packet(self): with self.lock: packetid, packet = self.world.sector_packets.popleft() if packetid == 1: # Entire Sector blocks, sectors = self.world, self.world.sectors secpos = struct.unpack("iii", packet[:12]) sector = sectors[secpos] cx, cy, cz = sector_to_blockpos(secpos) fpos = 12 exposed_pos = fpos + 1024 for x in range(cx, cx+8): for y in range(cy, cy+8): for z in range(cz, cz+8): read = packet[fpos:fpos+2] fpos += 2 unpacked = structuchar2.unpack(read) if read != null2 and unpacked in BLOCKS_DIR: position = x,y,z try: blocks[position] = BLOCKS_DIR[unpacked] if blocks[position].sub_id_as_metadata: blocks[position] = type(BLOCKS_DIR[unpacked])() blocks[position].set_metadata(0) except KeyError: main_blk = BLOCKS_DIR[(unpacked[0], 0)] if main_blk.sub_id_as_metadata: # sub id is metadata blocks[position] = type(main_blk)() blocks[position].set_metadata(unpacked[-1]) sector.append(position) if packet[exposed_pos:exposed_pos+1] == b"1": blocks.show_block(position) exposed_pos += 1 if secpos in self.world.sector_queue: del self.world.sector_queue[secpos] #Delete any hide sector orders elif packetid == 2: # Blank Sector self.world.sectors[struct.unpack("iii", packet)] = [] elif packetid == 3: # Add Block self.world._add_block(struct.unpack("iii", packet[:12]), BLOCKS_DIR[struct.unpack("BB", packet[12:])]) elif packetid == 4: # Remove Block self.world._remove_block(struct.unpack("iii", packet)) elif packetid == 5: # Chat Print self.controller.write_line(packet[:-4].decode('utf-8'), color=struct.unpack("BBBB", packet[-4:])) if not self.controller.text_input.visible: self.controller.chat_box.visible = True pyglet.clock.unschedule(self.controller.hide_chat_box) pyglet.clock.schedule_once(self.controller.hide_chat_box, G.CHAT_FADE_TIME) elif packetid == 6: # Inventory player = self.controller.player caret = 0 for inventory in (player.quick_slots.slots, player.inventory.slots, player.armor.slots): for i in range(len(inventory)): id_main, id_sub, amount = struct.unpack("HBB", packet[caret:caret+4]) caret += 4 if id_main == 0: continue durability = -1 if id_main >= G.ITEM_ID_MIN and (id_main, id_sub) not in G.ITEMS_DIR: #The subid must be durability durability = id_sub * G.ITEMS_DIR[(id_main, 0)].durability // 255 id_sub = 0 inventory[i] = ItemStack(type=BlockID(id_main, id_sub), amount=amount, durability=durability) self.controller.item_list.update_items() self.controller.inventory_list.update_items() elif packetid == 7: # New player connected plyid, name = struct.unpack("H", packet[:2])[0], packet[2:].decode('utf-8') if plyid not in self.controller.player_ids: self.controller.player_ids[plyid] = Player(username=name, local_player=False) elif name == '\0': del self.controller.player_ids[plyid] elif packetid == 8: # Player Movement ply = self.controller.player_ids[struct.unpack("H", packet[:2])[0]] ply.momentum = struct.unpack("fff", packet[2:14]) ply.position = struct.unpack("ddd", packet[14:]) elif packetid == 9: # Player Jump self.controller.player_ids[struct.unpack("H", packet)[0]].dy = 0.016 elif packetid == 10: # Update Tile Entity self.world[struct.unpack("iii", packet[:12])].update_tile_entity(packet[12:]) elif packetid == 255: # Spawn Position self.controller.player.position = struct.unpack("iii", packet[:12]) packet = packet[12:] packet, seed = extract_string_packet(packet) self.world.biome_generator = BiomeGenerator(seed) #Now that we know where the player should be, we can enable .update again self.controller.update = self.controller.update_disabled else: warn("Received unknown packetid %s, there's probably a version mismatch between client and server!" % packetid)