import StringIO import array import math import sys import utils import blocks import config import logbot import fops from axisbox import AABB log = logbot.getlogger("GRID") class Chunk(object): levels = config.WORLD_HEIGHT / 16 biomes = [ None for _ in xrange(config.CHUNK_SIDE_LEN * config.CHUNK_SIDE_LEN) ] def __init__(self, coords): self.coords = coords self.x = coords[0] self.z = coords[1] self.grid_x = self.x << 4 self.grid_z = self.z << 4 self.block_types = [None for _ in xrange(self.levels)] self.meta = [None for _ in xrange(self.levels)] self.block_light = [] # ignore block light self.sky_light = [] # ifnore sky light
import heapq import config import logbot log = logbot.getlogger("ASTAR") class PathNode(object): def __init__(self, coords, cost=1): self.coords = coords self.cost = cost self.g = 0 self.h = 0 self.f = 0 self.step = 0 self._parent = None self.hash = hash(self.coords) def __str__(self): return "%s:%s:g%s:h%s:f%s" % \ (str(self.coords), self.cost, self.g, self.h, self.f) def __repr__(self): return self.__str__() def __lt__(self, other): return self.f < other.f
import re import logbot import utils log = logbot.getlogger("SIGNS") class Sign(object): def __init__(self, coords, line1, line2, line3, line4): self.coords = coords self.line1 = line1.strip().lower() self.line2 = line2.strip().lower() self.line3 = line3.strip().lower() self.line4 = line4.strip().lower() self.value = None self.decode() self.is_waypoint = self.line1 == "waypoint" and self.line2 self.is_groupable = self.group and self.value is not None def decode(self): self.line2 = re.sub(ur"\s+", " ", self.line2).strip() self.line3 = re.sub(ur"\s+", " ", self.line3).strip() self.line4 = re.sub(ur"\s+", " ", self.line4).strip() self.name = self.line2 self.group = self.line3 try: self.value = float(re.sub(ur",", ".", self.line4)) except ValueError: self.value = None
import items import recipes import config import logbot import utils import fops import dig import packets import blocks from pathfinding import AStarBBCol, AStarCoords, AStarMultiCoords from gridspace import GridSpace from inventory import InventoryManipulation log = logbot.getlogger("BEHAVIOUR_TREE") class Status(object): success = 20 failure = 30 running = 40 suspended = 50 class Priorities(object): idle = 0 user_command = 10 class BlackBoard(object):
import random from collections import defaultdict from twisted.internet.defer import Deferred import items import logbot import utils log = logbot.getlogger("INVENTORY") class InvetoryBase(object): base_slots = 36 def __init__(self, extra_slots, window_id, inventory_container): self.extra_slots = extra_slots + 1 self.window_id = window_id self.inventory_container = inventory_container self.slots = [None for _ in xrange(self.extra_slots + self.base_slots)] def __repr__(self): return self.__class__.__name__ def close_window(self): self.inventory_container.close_window() def set_slot(self, position, itemstack): self.slots[position] = itemstack
import re from collections import deque from pyparsing import ParseException, Word, OneOrMore, alphanums import config import behavior_tree as bt import logbot log = logbot.getlogger("CHAT") class Chat(object): clean_colors_re = re.compile(ur'\u00A7.', re.UNICODE) commander_name = Word(alphanums + '_').setResultsName("commander") commander_head_chat = "<" + commander_name + ">" commander_head_whisper = commander_name + OneOrMore(Word(alphanums)) + ":" command_part = OneOrMore(Word(alphanums)).setResultsName("command") commander_message = (commander_head_chat | commander_head_whisper) + command_part def __init__(self, world): self.world = world self.chat_spam_treshold_count = 0 self.chat_spam_treshold_buffer = deque() def tick(self): if self.chat_spam_treshold_count > 0: self.chat_spam_treshold_count -= 1 if self.chat_spam_treshold_count <= 160 and self.chat_spam_treshold_buffer: log.msg("consume chat buffer size %d" %
import re import logbot import utils import materials import fops import config import block_details from axisbox import AABB log = logbot.getlogger("BLOCKS") block_list = [None for _ in xrange(256)] block_map = {} wood_names = ["Oak", "Spruce", "Birch", "Jungle"] stone_lab_names = [ "Stone", "Sandstone", None, "Cobblestone", "Brick", "Stone Brick", "Nether Brick", "Quartz" ] class BlockMetaClass(type): def __new__(meta, name, bases, dct): cls = super(BlockMetaClass, meta).__new__(meta, name, bases, dct) def name_or_class(cls, name): try: subcls = globals()[name] return issubclass(cls, subcls) except KeyError:
from collections import defaultdict import items import blocks import logbot log = logbot.getlogger("RECIPES") recipe_map = {} recipes_count = defaultdict(int) class RecipeMetaClass(type): def __new__(meta, name, bases, dct): cls = super(RecipeMetaClass, meta).__new__(meta, name, bases, dct) if hasattr(cls, "name"): cls.resources = [] cls.itemstack = items.item_db.item_by_name(cls.name, count=cls.count) # if cls.itemstack.common: # print 'recipes check', cls if issubclass(cls, MineBluePrint): cls.type = "mine" cls.block = blocks.block_map[cls.block] elif issubclass(cls, SmeltBluePrint): cls.type = "smelt" cls.smelt_item = items.item_db.item_by_name(cls.smelt_item) cls.resources = [cls.smelt_item] elif issubclass(cls, CraftBluePrint): cls.type = "craft"
from collections import defaultdict import items import blocks import logbot log = logbot.getlogger("RECIPES") recipe_map = {} recipes_count = defaultdict(int) class RecipeMetaClass(type): def __new__(meta, name, bases, dct): cls = super(RecipeMetaClass, meta).__new__(meta, name, bases, dct) if hasattr(cls, 'name'): cls.resources = [] cls.itemstack = items.item_db.item_by_name(cls.name, count=cls.count) #if cls.itemstack.common: # print 'recipes check', cls if issubclass(cls, MineBluePrint): cls.type = 'mine' cls.block = blocks.block_map[cls.block] elif issubclass(cls, SmeltBluePrint): cls.type = 'smelt' cls.smelt_item = items.item_db.item_by_name(cls.smelt_item) cls.resources = [cls.smelt_item] elif issubclass(cls, CraftBluePrint): cls.type = 'craft' if cls.plan is not None:
from collections import defaultdict import logbot import items import blocks log = logbot.getlogger("STATISTICS") GENERAL_STATS = 1000 ACHIEVEMENTS = 5242880 BLOCK_MINED = 16777216 ITEM_CRAFTED = 16842752 ITEM_USED = 16908288 ITEM_BREAKED = 16973824 ACHIEVEMENT_NAMES = [ "openInventory", "mineWood", "buildWorkBench", "buildPickaxe", "buildFurnace", "acquireIron", "buildHoe", "makeBread", "bakeCake", "buildBetterPickaxe", "cookFish", "onARail", "buildSword", "killEnemy",
import collections import logbot import items import utils import config from axisbox import AABB from utils import Vector log = logbot.getlogger("ENTITIES") class Entity(object): def __init__(self, eid=None, x=None, y=None, z=None): self.eid = eid self.x = x self.y = y self.z = z self.velocity = Vector(0, 0, 0) self.is_bot = False self.is_mob = False self.is_player = False self.is_xp_orb = False self.is_object = False self.is_itemstack = False self.is_painting = False def __hash__(self): return self.eid
# -*- coding: utf-8 -*- """ A high-level interface for the bot. @author: silver """ from inventory import LEFT_CLICK, RIGHT_CLICK, WID_INVENTORY, WID_MOUSE import logbot import entities import items import plugins log = logbot.getlogger("INTERFACE") class BotInterface(object): """This is meant to be a high-level abstraction of the bot, implementing all aspects of a normal player interface, as well as being a central, unified location for bot behaviour access gained through plugins.""" def __init__(self, bot_entity): self._entity = bot_entity self.world = bot_entity.world self.behaviours = plugins.behaviours self.verbs = {} for plugin in plugins.behaviours: plugin = plugins.behaviours[plugin] for verb in plugin.verbs: if verb in self.verbs:
from collections import defaultdict import logbot import items import blocks log = logbot.getlogger("STATISTICS") GENERAL_STATS = 1000 ACHIEVEMENTS = 5242880 BLOCK_MINED = 16777216 ITEM_CRAFTED = 16842752 ITEM_USED = 16908288 ITEM_BREAKED = 16973824 ACHIEVEMENT_NAMES = ["openInventory", "mineWood", "buildWorkBench", "buildPickaxe", "buildFurnace", "acquireIron", "buildHoe", "makeBread", "bakeCake", "buildBetterPickaxe", "cookFish", "onARail", "buildSword", "killEnemy",
from twisted.internet.protocol import ReconnectingClientFactory, Protocol from twisted.internet import reactor import config import logbot import proxy_processors.default import utils from packets import parse_packets, make_packet, packets_by_name, Container from proxy_processors.default import process_packets as packet_printout proxy_processors.default.ignore_packets = [] proxy_processors.default.filter_packets = [] log = logbot.getlogger("PROTOCOL") class MineCraftProtocol(Protocol): def __init__(self, world): self.world = world self.world.protocol = self self.leftover = "" self.encryption_on = False self.packets = deque() self.router = { 0: self.p_ping, 1: self.p_login, 3: self.p_chat, 4: self.p_time,
from collections import defaultdict, OrderedDict from twisted.internet.task import cooperate import tools import logbot from signwaypoints import SignWayPoints from gridspace import GridSpace log = logbot.getlogger("navgrid") class ChunkBorders(object): def __init__(self): self.borders = defaultdict(lambda: defaultdict(set)) def chunk_diff(self, c1, c2): return (c1[0] - c2[0], c1[1] - c2[1]) def add(self, from_crd, to_crd): chunk_from = from_crd[0] >> 4, from_crd[2] >> 4 chunk_to = to_crd[0] >> 4, to_crd[2] >> 4 ch_diff = self.chunk_diff(chunk_from, chunk_to) self.borders[chunk_from][ch_diff].add(to_crd) def remove(self, crd): chunk_from = crd[0] >> 4, crd[2] >> 4 for i in [-1, 1]: for j in [-1, 1]:
import re import logbot import utils log = logbot.getlogger("SIGNS") class Sign(object): def __init__(self, coords, line1, line2, line3, line4): self.coords = coords self.line1 = line1.strip().lower() self.line2 = line2.strip().lower() self.line3 = line3.strip().lower() self.line4 = line4.strip().lower() self.value = None self.decode() self.is_waypoint = self.line1 == "waypoint" self.is_groupable = self.group and self.value is not None def decode(self): self.line2 = re.sub(ur"\s+", " ", self.line2) self.line3 = re.sub(ur"\s+", " ", self.line3) self.line4 = re.sub(ur"\s+", " ", self.line4) try: self.name = self.line4 self.value = float(re.sub(ur",", ".", self.line2)) except ValueError: self.name = self.line2 self.value = None self.group = self.line3
import plugins.core import plugins.custom import logbot import utils from plugins.base import PluginChatBase log = logbot.getlogger("EVENTREGISTER") class EventHook(object): def __init__(self): self.handlers = [] def fire(self, *args, **kwargs): for handler in self.handlers: handler(*args, **kwargs) def subscribe(self, f): self.handlers.append(f) def unsubscribe(self, f): self.handlers.remove(f) @property def no_handlers(self): return len(self.handlers) == 0
# -*- coding: utf-8 -*- """ A high-level interface for the bot. @author: silver """ from inventory import LEFT_CLICK, RIGHT_CLICK, WID_INVENTORY, WID_MOUSE import logbot import entities import items import plugins log = logbot.getlogger('INTERFACE') class BotInterface(object): """This is meant to be a high-level abstraction of the bot, implementing all aspects of a normal player interface, as well as being a central, unified location for bot behaviour access gained through plugins.""" def __init__(self, bot_entity): self._entity = bot_entity self.world = bot_entity.world self.behaviours = plugins.behaviours self.verbs = {} for plugin in plugins.behaviours: plugin = plugins.behaviours[plugin] for verb in plugin.verbs: if verb in self.verbs: msg = 'Cannot override pre-existing verb "%s"' % verb
import random from collections import defaultdict from twisted.internet.defer import Deferred import items import logbot import utils import entities log = logbot.getlogger("INVENTORY") class InvetoryBase(object): base_slots = 36 def __init__(self, extra_slots, window_id, inventory_container): self.extra_slots = extra_slots + 1 self.window_id = window_id self.inventory_container = inventory_container self.slots = [None for _ in xrange(self.extra_slots + self.base_slots)] def __repr__(self): return self.__class__.__name__ def close_window(self): self.inventory_container.close_window() def set_slot(self, position, itemstack): self.slots[position] = itemstack
from construct import Flag, PascalString, Adapter from construct import UBInt8, UBInt16, UBInt32 from construct import SBInt8, SBInt16, SBInt32, SBInt64 from construct import BFloat32, BFloat64 from construct import BitStruct, BitField from construct import StringAdapter, LengthValueAdapter, Sequence from pynbt import NBTFile import logbot # Strings. # This one is a UCS2 string, which effectively decodes single writeChar() # invocations. We need to import the encoding for it first, though. log = logbot.getlogger("BOT_ENTITY") def ucs2(name): if name.lower() not in ("ucs2", "ucs-2"): return None def ucs2_encode(data, errors="replace"): data = u"".join(i if ord(i) < 65536 else u"?" for i in data) return utf_16_be_encode(data, errors) ucs2_decode = utf_16_be_decode class UCS2IncrementalEncoder(IncrementalEncoder): def encode(self, input, final=False): return ucs2_encode(input, self.errors)[0]
def __init__(self, world): self.world = world self.packets_in = 0 self.node_count = 0 self.edge_count = 0 self.logger = logbot.getlogger("BOT_ENTITY_STATUS")
import fops import logbot import blocks import config from axisbox import AABB log = logbot.getlogger("GRIDSPACE") class GridSpace(object): def __init__(self, grid, coords=None, block=None, bb=None): self.grid = grid self.bb_stand = None if block is not None: self.block = block self.coords = self.block.coords elif coords is not None: self.coords = coords self.block = self.grid.get_block(coords[0], coords[1], coords[2]) elif bb is not None: self.bb_stand = bb self.block = self.grid.standing_on_block(bb) if self.block is None: self.block = self.grid.get_block(*bb.grid_bottom_center) self.coords = self.block.coords else: raise Exception("Empty gridspace object")
import heapq import time import config import logbot from gridspace import GridSpace from axisbox import AABB log = logbot.getlogger("ASTAR") class BaseEx(Exception): def __init__(self, value=None): self.value = value def __repr__(self): if self.value is None: return self.__class__.__name__ else: return "%s %s" % (self.__class__.__name__, self.value) @property def message(self): return str(self) class PathNotFound(BaseEx): pass
# -*- coding: utf-8 -*- #import sys #import inspect from resources import namedata #import blocks import logbot try: from cStringIO import StringIO except: from StringIO import StringIO log = logbot.getlogger("ITEMS") class Slot(object): # Slotdata id = -1 count = None damage = None #size = <auto-calculated> data = None # referring-container info. This is needed by the Mouse 'window' to # know which window to 'click' on and where. wid = None gc_slot_number = None window_slot_number = None
from collections import deque from twisted.internet.protocol import ReconnectingClientFactory, Protocol from twisted.internet import reactor import config import logbot import proxy_processors.default import utils from packets import parse_packets, make_packet, packets_by_name, Container from proxy_processors.default import process_packets as packet_printout proxy_processors.default.ignore_packets = [] proxy_processors.default.filter_packets = [] log = logbot.getlogger("FACTORY") # Packet debugging enabled by default if debugging is on. log_packet_types = dict([(x, False) for x in xrange(256)]) # Disable packet debugging for these packet types: enabled_packets = [] for pack in enabled_packets: log_packet_types[pack] = True class MineCraftProtocol(Protocol): def __init__(self, world): self.world = world self.world.protocol = self self.leftover = ""
import logbot from gridspace import GridSpace from axisbox import AABB log = logbot.getlogger("ENTITIES") class Entity(object): def __init__(self, **kwargs): self.eid = kwargs["eid"] self.x = kwargs["x"] self.y = kwargs["y"] self.z = kwargs["z"] self.velocity = None self.is_bot = False @property def position(self): return (self.x / 32.0, self.y / 32.0, self.z / 32.0) @property def grid_position(self): x = self.x / 32 y = self.y / 32 z = self.z / 32 return (x, y, z)
def import_encryption(): global encryption try: import encryption except ImportError: log.err( 'Encryption is demanded but PyCrypto not installed. This is not going to have a good end.' ) proxy_processors.default.ignore_packets = [] proxy_processors.default.filter_packets = [] log = logbot.getlogger("PROTOCOL") class MineCraftProtocol(Protocol): def __init__(self, world): self.world = world self.world.protocol = self self.event = world.eventregister self.leftover = "" self.encryption_on = False self.packets = deque() self.router = { 0: self.p_ping, 1: self.p_login, 3: self.p_chat,
import StringIO import array import math import sys import utils import blocks import config import logbot import fops from axisbox import AABB log = logbot.getlogger("GRID") class Chunk(object): levels = config.WORLD_HEIGHT / 16 biomes = [None for _ in xrange(config.CHUNK_SIDE_LEN * config.CHUNK_SIDE_LEN)] def __init__(self, coords): self.coords = coords self.x = coords[0] self.z = coords[1] self.grid_x = self.x << 4 self.grid_z = self.z << 4 self.block_types = [None for _ in xrange(self.levels)] self.meta = [None for _ in xrange(self.levels)] self.block_light = [] # ignore block light self.sky_light = [] # ifnore sky light
import inspect import sys import logbot import tools import materials import fops from axisbox import AABB log = logbot.getlogger("BLOCKS") class Block(object): slipperiness = 0.6 render_as_normal_block = True is_opaque_cube = True bounding_box = AABB(0.0, 0.0, 0.0, 1.0, 1.0, 1.0) def __init__(self, grid=None, x=None, y=None, z=None, meta=0): if grid.__class__.__name__ != "Grid": raise Exception( "bad parameter to Block. Expecting World, received %s" % grid.__class__.__name__) self.grid = grid self.x = x self.y = y self.z = z self.meta = meta
import logbot import utils import config import entities import inventory from items import Item from entities import Entities from grid import Grid from statistics import Statistics from chat import Chat from botentity import BotEntity from signwaypoints import SignWayPoints log = logbot.getlogger("WORLD") class Dimension(object): def __init__(self, world): self.world = world self.entities = Entities(self) self.grid = Grid(self) self.sign_waypoints = SignWayPoints(self) class DummyQueue(object): close = lambda s: None empty = lambda s: True full = lambda s: True get = close
import logbot import utils import fops log = logbot.getlogger("GRIDSPACE") class NodeState(object): def __init__(self, grid, x=None, y=None, z=None, vector=None): self.grid = grid self.x = x self.y = y self.z = z self.coords = utils.Vector(self.x, self.y, self.z) self.block_0 = grid.get_block(self.x, self.y - 1, self.z) self.block_1 = grid.get_block(self.x, self.y, self.z) self.block_2 = grid.get_block(self.x, self.y + 1, self.z) self.can_be = self.block_1.can_fall_through and self.block_2.can_fall_through self.can_stand = self.block_0.can_stand_on and self.can_be self.can_jump = self.can_stand and self.block_1.is_free and self.block_2.is_free self.can_fall = self.can_be and self.block_0.can_fall_through self.can_climb = self.can_be and self.block_1.is_climbable self.in_fire = self.block_1.is_burning or self.block_2.is_burning self.in_water = self.block_1.is_water or self.block_2.is_water self.can_hold = self.in_water or self.block_1.is_ladder or ( self.block_1.is_vine and self.block_1.is_climbable) self.platform_y = self.y self.center_x = self.x + 0.5 self.center_z = self.z + 0.5 def __repr__(self):
Furnace(Window): Dispenser(Window): EnchantmentTable(Window): ..the expected thing to hold here would be Item objects from the items module. @author: Brian Visel """ import logbot from items import Item, NoItem from Queue import Queue, Full, Empty from construct import Container log = logbot.getlogger('INVENTORY') WID_INVENTORY = 0 WID_MOUSE = -1 TYPE_CHEST = 0 TYPE_CRAFTING = 1 TYPE_FURNACE = 2 TYPE_DISPENSER = 3 TYPE_ENCHANTMENT = 4 #TYPE_BREWING = 5 # Mouse clicks OUTSIDE_WINDOW = -999 LEFT_CLICK = 0 RIGHT_CLICK = 1
import re import blocks import logbot import materials log = logbot.getlogger("ITEMS") item_list = [None for _ in xrange(2300)] class ToolMaterial(object): def __init__(self, harvest_level, max_uses, efficiency_on_proper_material, damage_vs_entity, enchantability): self.harvest_level = harvest_level self.max_uses = max_uses self.efficiency_on_proper_material = efficiency_on_proper_material self.damage_vs_entity = damage_vs_entity self.enchantability = enchantability class EnumToolMaterial(object): WOOD = ToolMaterial(0, 59, 2.0, 0, 15) STONE = ToolMaterial(1, 131, 4.0, 1, 5) IRON = ToolMaterial(2, 250, 6.0, 2, 14) DIAMOND = ToolMaterial(3, 1561, 8.0, 3, 10) GOLD = ToolMaterial(0, 32, 12.0, 0, 22) class ArmorMaterial(object): def __init__(self, damage_factor, damage_reduction_amount_array,
import math from twisted.internet.task import cooperate from twisted.internet.defer import inlineCallbacks, returnValue import config import tools import logbot import fops from gridspace import GridSpace from pathfinding import AStar log = logbot.getlogger("BEHAVIOURS") class Status(object): success = 20 failure = 30 running = 40 suspended = 50 class BehaviourManager(object): def __init__(self, world, bot): self.world = world self.bot = bot self.bqueue = [] self.default_behaviour = LookAtPlayerBehaviour(self) self.running = False
import re from collections import deque import config import behaviours import logbot log = logbot.getlogger("CHAT") class Chat(object): def __init__(self, world): self.world = world self.clean_colors_re = re.compile(ur'\u00A7.', re.UNICODE) self.commander_re = re.compile( ur'<%s> .*' % self.world.commander.name.lower(), re.UNICODE) self.wspace_re = re.compile(ur"\s+") self.chat_spam_treshold_count = 0 self.chat_spam_treshold_buffer = deque() def tick(self): if self.chat_spam_treshold_count > 0: self.chat_spam_treshold_count -= 1 if self.chat_spam_treshold_count <= 160 and self.chat_spam_treshold_buffer: self.send_chat_message(self.chat_spam_treshold_buffer.popleft()) def send_chat_message(self, msg): log.msg(">> %s" % msg) if self.world.commander.in_game: self.chat_spam_treshold_count += 20
from collections import defaultdict from datetime import datetime import logbot import utils import config import inventory from entities import Entities from grid import Grid from statistics import Statistics from chat import Chat from botentity import BotEntity from signwaypoints import SignWayPoints from eventregister import EventRegister log = logbot.getlogger("WORLD") class Dimension(object): def __init__(self, world): self.world = world self.entities = Entities(self) self.grid = Grid(self) self.sign_waypoints = SignWayPoints(self) class World(object): def __init__(self, host=None, port=None, commander_name=None,