# This file allows you to programmatically create blocks in Craft. # Please use this wisely. Test on your own server first. Do not abuse it. import requests import socket import sqlite3 import sys DEFAULT_HOST = '127.0.0.1' DEFAULT_PORT = 4080 EMPTY = 0 GRASS = 1 SAND = 2 STONE = 3 BRICK = 4 WOOD = 5 CEMENT = 6 DIRT = 7 PLANK = 8 SNOW = 9 GLASS = 10 COBBLE = 11 LIGHT_STONE = 12 DARK_STONE = 13 CHEST = 14 LEAVES = 15 CLOUD = 16 TALL_GRASS = 17 YELLOW_FLOWER = 18 RED_FLOWER = 19 PURPLE_FLOWER = 20 SUN_FLOWER = 21 WHITE_FLOWER = 22 BLUE_FLOWER = 23 OFFSETS = [ (-0.5, -0.5, -0.5), (-0.5, -0.5, 0.5), (-0.5, 0.5, -0.5), (-0.5, 0.5, 0.5), (0.5, -0.5, -0.5), (0.5, -0.5, 0.5), (0.5, 0.5, -0.5), (0.5, 0.5, 0.5), ] def sphere(cx, cy, cz, r, fill=False, fx=False, fy=False, fz=False): result = set() for x in range(cx - r, cx + r + 1): if fx and x != cx: continue for y in range(cy - r, cy + r + 1): # if y < cy: # continue # top hemisphere only if fy and y != cy: continue for z in range(cz - r, cz + r + 1): if fz and z != cz: continue inside = False outside = fill for dx, dy, dz in OFFSETS: ox, oy, oz = x + dx, y + dy, z + dz d2 = (ox - cx) ** 2 + (oy - cy) ** 2 + (oz - cz) ** 2 d = d2 ** 0.5 if d < r: inside = True else: outside = True if inside and outside: result.add((x, y, z)) return result def circle_x(x, y, z, r, fill=False): return sphere(x, y, z, r, fill, fx=True) def circle_y(x, y, z, r, fill=False): return sphere(x, y, z, r, fill, fy=True) def circle_z(x, y, z, r, fill=False): return sphere(x, y, z, r, fill, fz=True) def cylinder_x(x1, x2, y, z, r, fill=False): x1, x2 = sorted((x1, x2)) result = set() for x in range(x1, x2 + 1): result |= circle_x(x, y, z, r, fill) return result def cylinder_y(x, y1, y2, z, r, fill=False): y1, y2 = sorted((y1, y2)) result = set() for y in range(y1, y2 + 1): result |= circle_y(x, y, z, r, fill) return result def cylinder_z(x, y, z1, z2, r, fill=False): z1, z2 = sorted((z1, z2)) result = set() for z in range(z1, z2 + 1): result |= circle_z(x, y, z, r, fill) return result def cuboid(x1, x2, y1, y2, z1, z2, fill=True): x1, x2 = sorted((x1, x2)) y1, y2 = sorted((y1, y2)) z1, z2 = sorted((z1, z2)) result = set() a = (x1 == x2) + (y1 == y2) + (z1 == z2) for x in range(x1, x2 + 1): for y in range(y1, y2 + 1): for z in range(z1, z2 + 1): n = 0 n += x in (x1, x2) n += y in (y1, y2) n += z in (z1, z2) if not fill and n <= a: continue result.add((x, y, z)) return result def pyramid(x1, x2, y, z1, z2, fill=False): x1, x2 = sorted((x1, x2)) z1, z2 = sorted((z1, z2)) result = set() while x2 >= x1 and z2 >= z2: result |= cuboid(x1, x2, y, y, z1, z2, fill) y, x1, x2, z1, z2 = y + 1, x1 + 1, x2 - 1, z1 + 1, z2 - 1 return result def get_identity(): query = ( 'select username, token from identity_token where selected = 1;' ) conn = sqlite3.connect('auth.db') rows = conn.execute(query) for row in rows: return row raise Exception('No identities found.') class Client(object): def __init__(self, host, port): self.conn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.conn.connect((host, port)) self.authenticate() def authenticate(self): username, identity_token = get_identity() url = 'https://craft.michaelfogleman.com/api/1/identity' payload = { 'username': username, 'identity_token': identity_token, } response = requests.post(url, data=payload) if response.status_code == 200 and response.text.isalnum(): access_token = response.text self.conn.sendall('A,%s,%s\n' % (username, access_token)) else: raise Exception('Failed to authenticate.') def set_block(self, x, y, z, w): self.conn.sendall('B,%d,%d,%d,%d\n' % (x, y, z, w)) def set_blocks(self, blocks, w): key = lambda block: (block[1], block[0], block[2]) for x, y, z in sorted(blocks, key=key): self.set_block(x, y, z, w) def bitmap(self, sx, sy, sz, d1, d2, data, lookup): x, y, z = sx, sy, sz dx1, dy1, dz1 = d1 dx2, dy2, dz2 = d2 for row in data: x = sx if dx1 else x y = sy if dy1 else y z = sz if dz1 else z for c in row: w = lookup.get(c) if w is not None: self.set_block(x, y, z, w) x, y, z = x + dx1, y + dy1, z + dz1 x, y, z = x + dx2, y + dy2, z + dz2 def get_client(): default_args = [DEFAULT_HOST, DEFAULT_PORT] args = sys.argv[1:] + [None] * len(default_args) host, port = [a or b for a, b in zip(args, default_args)] client = Client(host, int(port)) return client def main(): client = get_client() set_block = client.set_block set_blocks = client.set_blocks # set_blocks(circle_y(0, 32, 0, 16, True), STONE) # set_blocks(circle_y(0, 33, 0, 16), BRICK) # set_blocks(cuboid(-1, 1, 1, 31, -1, 1), CEMENT) # set_blocks(cuboid(-1024, 1024, 32, 32, -3, 3), STONE) # set_blocks(cuboid(-3, 3, 32, 32, -1024, 1024), STONE) # set_blocks(cuboid(-1024, 1024, 33, 33, -3, -3), BRICK) # set_blocks(cuboid(-1024, 1024, 33, 33, 3, 3), BRICK) # set_blocks(cuboid(-3, -3, 33, 33, -1024, 1024), BRICK) # set_blocks(cuboid(3, 3, 33, 33, -1024, 1024), BRICK) # set_blocks(sphere(0, 32, 0, 16), GLASS) # for y in range(1, 32): # set_blocks(circle_y(0, y, 0, 4, True), CEMENT) # set_blocks(circle_x(16, 33, 0, 3), BRICK) # set_blocks(circle_x(-16, 33, 0, 3), BRICK) # set_blocks(circle_z(0, 33, 16, 3), BRICK) # set_blocks(circle_z(0, 33, -16, 3), BRICK) # for x in range(0, 1024, 32): # set_blocks(cuboid(x - 1, x + 1, 31, 32, -1, 1), CEMENT) # set_blocks(cuboid(-x - 1, -x + 1, 31, 32, -1, 1), CEMENT) # set_blocks(cuboid(x, x, 1, 32, -1, 1), CEMENT) # set_blocks(cuboid(-x, -x, 1, 32, -1, 1), CEMENT) # for z in range(0, 1024, 32): # set_blocks(cuboid(-1, 1, 31, 32, z - 1, z + 1), CEMENT) # set_blocks(cuboid(-1, 1, 31, 32, -z - 1, -z + 1), CEMENT) # set_blocks(cuboid(-1, 1, 1, 32, z, z), CEMENT) # set_blocks(cuboid(-1, 1, 1, 32, -z, -z), CEMENT) # for x in range(0, 1024, 8): # set_block(x, 32, 0, CEMENT) # set_block(-x, 32, 0, CEMENT) # for z in range(0, 1024, 8): # set_block(0, 32, z, CEMENT) # set_block(0, 32, -z, CEMENT) # set_blocks(pyramid(32, 32+64-1, 12, 32, 32+64-1), COBBLE) # outer = circle_y(0, 11, 0, 176 + 3, True) # inner = circle_y(0, 11, 0, 176 - 3, True) # set_blocks(outer - inner, STONE) # a = sphere(-32, 48, -32, 24, True) # b = sphere(-24, 40, -24, 24, True) # set_blocks(a - b, PLANK) # set_blocks(cylinder_x(-64, 64, 32, 0, 8), STONE) # data = [ # '...............................', # '..xxx..xxxx...xxx..xxxxx.xxxxx.', # '.x...x.x...x.x...x.x.......x...', # '.x.....xxxx..xxxxx.xxx.....x...', # '.x...x.x..x..x...x.x.......x...', # '..xxx..x...x.x...x.x.......x...', # '...............................', # ] # lookup = { # 'x': STONE, # '.': PLANK, # } # client.bitmap(0, 32, 32, (1, 0, 0), (0, -1, 0), data, lookup) if __name__ == '__main__': main()