Exemplo n.º 1
0
def enemyNextMove(enemy: Enemy, game: Dungeon):
    """
    Selects the next move for a given enemy according to the predetermined
    move strategies for enemies. If no valid moves are possible,
    then returns the enemy's location.
    """
    enemyBoardNum = whichBoardInLevel(game.levels[game.currLevel],
                                      enemy.location)
    possMoves = enemyPossibleMoves(enemy, game)
    log("possible enemy moves to choose from:", str(possMoves))
    if len(possMoves) == 0:
        return enemy.location

    playersInOurRoom, playersInOurLevel = getPlayersInRoomAndLevel(
        enemyBoardNum, game)

    if len(playersInOurRoom) != 0:
        playerLocs = [player.location for player in playersInOurRoom]
        return enemyStrat(possMoves, playerLocs)
    elif len(playersInOurLevel) != 0:
        playerLocs = [player.location for player in playersInOurLevel]
        return enemyStrat(possMoves, playerLocs)
    else:  # No valid move
        log("shouldn't EVER EZVER EVER get here. green man you must MOVE")
        return enemy.location
Exemplo n.º 2
0
def benchmark_B(handsfile):
    from MrIf import MrIf
    from MrGreed import MrGreed
    from MrZeroTree import MrZeroTree
    from OfflineInterface import OfflineInterface, read_std_hands, play_a_test

    ifs = [MrIf(room=255, place=i, name='I%d' % (i)) for i in range(4)]
    gs = [MrGreed(room=255, place=i, name='G%d' % (i)) for i in range(4)]
    zs = [
        MrZeroTree(room=255,
                   place=i,
                   name='Z%d' % (i),
                   mcts_b=10,
                   mcts_k=2,
                   sample_b=-1,
                   sample_k=-2) for i in [0, 2]
    ]
    I_GI = OfflineInterface([gs[0], ifs[1], gs[2], ifs[3]], print_flag=False)
    I_ZG = OfflineInterface([zs[0], gs[1], zs[1], gs[3]], print_flag=False)

    hands = read_std_hands(handsfile)
    stats = []
    for k, hand in hands:
        stats.append(play_a_test(I_ZG, hand, 2))
        print("%4d" % (stats[-1], ), end=" ", flush=True)
    else:
        print("")
    log("benchmark result: %.2f %.2f" %
        (numpy.mean(stats), numpy.sqrt(numpy.var(stats) / (len(stats) - 1))))
Exemplo n.º 3
0
 def save_to_checkpoint(self, path=None):
     if path is None:
         path = self.config.checkpoint_path
     self.saver.save(self.sess,
                     path + 'model.ckpt',
                     global_step=self.global_step)
     log('checkpoint has been saved to :' + path + 'model.ckpt')
Exemplo n.º 4
0
def gen_data_for_o(N1=2,N2=1,save=False):
    from OfflineInterface import OfflineInterface
    import pickle
    global for_o
    for_o=([],[],[],[])
    g=[MrGreed(room=0,place=i,name='greed%d'%(i)) for i in range(4)]
    offlineinterface=OfflineInterface(g,print_flag=False)
    stats=[]
    for k,l in itertools.product(range(N1),range(N2)):
        if l==0:
            cards=offlineinterface.shuffle()
        else:
            cards=cards[39:52]+cards[0:39]
            offlineinterface.shuffle(cards=cards)
        for i,j in itertools.product(range(13),range(4)):
            offlineinterface.step()
        stats.append(offlineinterface.clear())
        print(".",end=" ",flush=True)
        offlineinterface.prepare_new()
    print("")
    if save:
        with open("Greed_%d.data"%(N1),'wb') as f:
            pickle.dump(for_o,f)
        log("saved")
    return for_o
Exemplo n.º 5
0
def example_DJ():
    zt3 = MrZeroTree(room=255,
                     place=3,
                     name='zerotree3',
                     mcts_b=10,
                     mcts_k=2,
                     sample_b=-1,
                     sample_k=-2)

    zt3.cards_list = [
        "HQ", "HJ", "H8", "SA", "S5", "S4", "S3", "CQ", "CJ", "C4"
    ]
    zt3.cards_on_table = [1, "DJ", "D8"]
    zt3.history = [[0, "H3", "H5", "H4", "H7"], [3, "S6", "SJ", "HK", "S10"],
                   [0, "DQ", "DA", "D9", "D3"]]
    zt3.scores = [["HK"], [], [], ["H3", "H5", "H4", "H7"]]
    """cards_dict=MrGreed.gen_cards_dict(zt3.cards_list)
    legal_choice=MrGreed.gen_legal_choice("D",cards_dict,zt3.cards_list)
    zt3.select_interact_cards(legal_choice)"""
    """cards_played,scores_stage,void_info_stage=zt3.public_info()
    log(cards_played)
    for i in range(14):
        log("after stage %d: %s\n%s"%(i,scores_stage[i],void_info_stage[i]),end="")
        input()"""
    #log(zt3.pick_a_card())
    #return
    l = [zt3.pick_a_card() for i in range(50)]
    log("%d %d %d" % (len([i[0] for i in l if i[0] == "H"
                           ]), len([i[0] for i in l if i[0] == "C"
                                    ]), len([i[0] for i in l if i[0] == "S"])))
Exemplo n.º 6
0
def stat_r_log(fname):
    import re,numpy
    from Util import INIT_CARDS
    with open(fname,"r") as f:
        lines=f.readlines()
    dict_val={};dict_reg={}
    for l in lines:
        if "reg" in l:
            add_dict(l.split("reg")[1],dict_reg)
        elif "r/beta" in l:
            add_dict(l.split("r/beta")[1],dict_val)
    l_val=[(c,numpy.mean(dict_val[c]),numpy.sqrt(numpy.var(dict_val[c])),numpy.var(dict_val[c])/numpy.sqrt(len(dict_val[c])-1)) for c in INIT_CARDS]
    l_reg=[(c,numpy.mean(dict_reg[c]),numpy.sqrt(numpy.var(dict_reg[c])),numpy.var(dict_reg[c])/numpy.sqrt(len(dict_reg[c])-1)) for c in INIT_CARDS]

    """line_vals=[]
    for i in range(4):
        val=[v for c,v,s,e in l_val[i*13:i*13+13]]
        err=[e for c,v,s,e in l_val[i*13:i*13+13]]
        line_vals.append((l_val[i*13][0][0],val,err))"""
    line_val_vars=[]
    for i in range(4):
        var=[float("%.4f"%(s)) for c,v,s,e in l_val[i*13:i*13+13]]
        line_val_vars.append((l_val[i*13][0][0],var))
    line_regs=[]
    for i in range(4):
        val=[float("%.4f"%(v)) for c,v,s,e in l_reg[i*13:i*13+13]]
        err=[float("%.1e"%(e)) for c,v,s,e in l_reg[i*13:i*13+13]]
        line_regs.append((l_reg[i*13][0][0],val,err))
    """line_reg_vars=[]
    for i in range(4):
        var=[s for c,v,s,e in l_reg[i*13:i*13+13]]
        line_reg_vars.append((l_reg[i*13][0][0],var))"""
    log(line_regs)
    log(line_val_vars)
Exemplo n.º 7
0
 def close(self):
     """
     Closes the database connection. After calling this method, the instance will become unusable.
     """
     log(LogLevel.Info, "Closing database connection.")
     self._db_close()
     self.active = False
Exemplo n.º 8
0
def main():
    from MrZeroTree import BETA,MCTS_EXPL,BENCH_SMP_B,BENCH_SMP_K
    log("BETA: %.2f, VALUE_RENORMAL: %d, MCTS_EXPL: %d, BENCH_SMP_B: %d, BENCH_SMP_K: %.1f"\
        %(BETA,VALUE_RENORMAL,MCTS_EXPL,BENCH_SMP_B,BENCH_SMP_K))
    pv_net=PV_NET();log("init pv_net: %s"%(pv_net))
    #start_from="./ZeroNets/from-zero-14d/PV_NET-17-9479221-450.pkl"
    #pv_net=torch.load(start_from);log("start from: %s"%(start_from))
    train(pv_net)
Exemplo n.º 9
0
 def save(self):
     """
     Saves this Thing to the database, only if it has been changed since it was last loaded.
     """
     if self._dirty:
         log(LogLevel.Trace, "ThingProxy#{0}: Saving dirty Thing".format(self._id))
         self._thing.force_save()
         self._dirty = False
Exemplo n.º 10
0
def getWorld():
    global _world
    if not _world:
        # Instantiate singleton
        log(LogLevel.Debug, "Instantiating world singleton")
        _world = World()
    
    return _world
Exemplo n.º 11
0
def test_3rd():
    g0=MrGreed(room=0,place=0,name="if0")
    g0.history=[(0,'C2','C3','C4','C5'),(3,'C6','C7','D2','C8'),(2,'D3','D4','D5','D6'),(1,'S2','S3','S4','S5')]
    g0.cards_list=['H6','H7','HJ','HA','SQ','DJ','DK']
    g0.cards_on_table=[2,'H8','HQ']
    #g0.cards_on_table=[2,'CA','CJ']
    log(g0.cards_list)
    log(g0.pick_a_card())
Exemplo n.º 12
0
def test_da():
    global print_level
    print_level=2
    g0=MrGreed(room=0,place=0,name="g0")
    g0.cards_list=['H2','H3','H4','H5','H6','H7','H8','H9','HJ','D9','DA']
    g0.history=[(2,'D3','D4','DJ','D6'),(1,'S2','S3','S4','S5')]
    g0.cards_on_table=[2, 'D7', 'D8']
    g0.scores=[[],[],[],['DJ']]
    log(g0.pick_a_card())
Exemplo n.º 13
0
 def save_object(self, thing):
     """
     Saves a modified object back to the database.
     """
     if not active:
         raise DatabaseNotConnected()
     log(LogLevel.Trace, "Saving {0} to the database...".format(thing))
     assert thing is not None, "Cannot save None!"
     self._db_save_object(thing)
Exemplo n.º 14
0
def log_source(s):
    s = s.split("\n")
    s2 = []
    for j, i in enumerate(s):
        if not i.strip().startswith("#") and len(i.strip()) > 0:
            #if i.strip().startswith("if"):
            #    s2.append(s[j-1])
            s2.append(i)
    log("\n".join(s2))
Exemplo n.º 15
0
 def connectionMade(self):
     h = self.transport.getHost()
     if type(h) is SSHTransportAddress:
         self.sshmode = True
         h = h.address
     log(LogLevel.Info, "Incoming connection from {0}".format(h))
     self.host = h.host
     if self.avatar:
         self.player = self.world.connect(self.avatar.username)
         self.complete_login()
Exemplo n.º 16
0
def test_legal_mask():
    n0 = MrNN(room=0, place=0, name="n0")
    n0.cards_list = [
        'S4', 'S6', 'S9', 'SA', 'H7', 'HK', 'DJ', 'C7', 'C8', 'CQ'
    ]
    n0.cards_on_table = [3, 'H8']
    mycards_oh = n0.gen_mycards_oh()
    log("get mycards_oh: %s" % (mycards_oh))
    legal_mask = n0.gen_legal_mask(mycards_oh)
    log("get legal_mask: %s" % (legal_mask))
Exemplo n.º 17
0
 def pick_a_card(self, suit=None):
     suit = self.decide_suit()
     log("%s, %s, %s, %s" %
         (self.name, suit, self.cards_on_table, self.cards_list))
     while True:
         choice = input("your turn: ")
         if choice in self.cards_list:
             break
         else:
             log("%s is not your cards. " % (choice), end="")
     return choice
def test_by_touchstone():
    h = [[0, 'CA', 'C10', 'CQ', 'C3'], [0, 'D3', 'DQ', 'D6', 'D9'],
         [1, 'S10', 'SA', 'SQ', 'SK'], [2, 'S4', 'SJ', 'S3', 'S6'],
         [3, 'H5', 'H8', 'H7', 'H9'], [2, 'H6', 'HJ', 'HQ', 'H10'],
         [0, 'S8', 'CK', 'CJ', 'S7'], [0, 'S9', 'D10', 'C6', 'S2'],
         [0, 'C9', 'C8', 'C4', 'D8'], [0, 'DK', 'D7', 'D4', 'DA'],
         [3, 'H4', 'HA', 'C7', 'HK']]
    s = ScenarioGen(2, h, [0, 'D5', 'C5'], ['C2', 'H3'], number=10, method=0)
    log(s.distribute_most_important(s.find_most_important()))
    log(s.void_info)
    print(list(s))
Exemplo n.º 19
0
 def lineReceived(self, line):
     log(LogLevel.Debug, "Received line: {0}".format(line))
     try:
         self.user.process_line(line)
     except Exception as ex:
         from traceback import print_exc
         print_exc(ex)
         self.write_line("Suddenly the dungeon collapses!! You die... (Server error)")
         self.terminal.loseConnection()
     self._cpos_input()
     self.terminal.eraseToDisplayEnd()
     self.drawInputLine()
Exemplo n.º 20
0
    def possi_rectify(self, cards_lists, thisuit):
        """
            posterior probability rectify
            cards_lists is in absolute order
        """
        cards_lists = copy.deepcopy(cards_lists)
        scores = copy.deepcopy(self.scores)
        result = 1.0
        for history in [
                self.cards_on_table,
        ] + self.history[::-1]:
            if len(history) == 5:
                for c in history[1:]:
                    if c in SCORE_DICT:
                        scores[last_winner].remove(c)
            last_winner = history[0]
            cards_on_table = copy.copy(history)
            pnext = (cards_on_table[0] + len(history) - 1) % 4
            for i in range(len(cards_on_table) - 1):
                pnext = (pnext - 1) % 4
                choice = cards_on_table.pop()
                cards_lists[pnext].append(choice)
                #不用修正我自己
                if pnext == self.place:
                    continue
                #决定是否需要修正
                nece = self.decide_rect_necessity(thisuit, choice)
                if nece < 0:
                    continue

                suit = cards_on_table[1][0] if len(cards_on_table) > 1 else "A"
                cards_dict = MrGreed.gen_cards_dict(cards_lists[pnext])
                legal_choice = MrGreed.gen_legal_choice(
                    suit, cards_dict, cards_lists[pnext])
                possi_pvnet = self.possi_rectify_pvnet(cards_lists, scores,
                                                       cards_on_table, pnext,
                                                       legal_choice, choice)
                if print_level >= 4:
                    log("rectify %s(%d): %.4e" % (choice, nece, possi_pvnet),
                        end="")
                    input()
                result *= possi_pvnet
        else:
            assert len(scores[0]) == len(scores[1]) == len(scores[2]) == len(
                scores[3]) == 0, "scores left not zero: %s" % (scores, )
            assert len(cards_lists[0]) == len(cards_lists[1]) == len(
                cards_lists[2]) == len(
                    cards_lists[3]) == 13, "cards_lists not equal 4x13: %s" % (
                        cards_lists, )
        if print_level >= 3:
            log("final cards possi: %.4e" % (result))
        return result
Exemplo n.º 21
0
    def pick_a_card(self):
        #确认桌上牌的数量和自己坐的位置相符
        assert (self.cards_on_table[0] + len(self.cards_on_table) -
                1) % 4 == self.place
        #utility datas
        suit = self.decide_suit()  #inherited from MrRandom
        cards_dict = MrGreed.gen_cards_dict(self.cards_list)
        #如果别无选择
        if cards_dict.get(suit) != None and len(cards_dict[suit]) == 1:
            choice = cards_dict[suit][0]
            if print_level >= 1:
                log("I have no choice but %s" % (choice))
            return choice

        if print_level >= 1:
            log("my turn: %s, %s" % (self.cards_on_table, self.cards_list))
        fmt_scores = MrGreed.gen_fmt_scores(
            self.scores
        )  #in absolute order, because self.scores is in absolute order
        #log("fmt scores: %s"%(fmt_scores))
        d_legal = {
            c: 0
            for c in MrGreed.gen_legal_choice(suit, cards_dict,
                                              self.cards_list)
        }  #dict of legal choice
        sce_gen = ScenarioGen(self.place,
                              self.history,
                              self.cards_on_table,
                              self.cards_list,
                              number=MrRandTree.N_SAMPLE,
                              METHOD1_PREFERENCE=100)
        for cards_list_list in sce_gen:
            cards_lists = [None, None, None, None]
            cards_lists[self.place] = copy.copy(self.cards_list)
            for i in range(3):
                cards_lists[(self.place + i + 1) % 4] = cards_list_list[i]
            if print_level >= 1:
                log("get scenario: %s" % (cards_lists))
            cards_on_table_copy = copy.copy(self.cards_on_table)
            gamestate = GameState(cards_lists, fmt_scores, cards_on_table_copy,
                                  self.place)
            searcher = mcts(iterationLimit=200, explorationConstant=100)
            searcher.search(initialState=gamestate)
            for action, node in searcher.root.children.items():
                if print_level >= 1:
                    log("%s: %s" % (action, node))
                d_legal[action] += node.totalReward / node.numVisits
        if print_level >= 1:
            log("d_legal: %s" % (d_legal))
            input("press any key to continue...")
        best_choice = MrGreed.pick_best_from_dlegal(d_legal)
        return best_choice
Exemplo n.º 22
0
    def requestAvatarId(self, credentials):
        try:
            user = credentials.username
            if self.db.player_login(user, credentials.password) == -1:
                log(LogLevel.Info, "{0} failed user authentication".format(user))
                return defer.fail(cred_error.UnauthorizedLogin("Authentication failure: No such user or bad password"))
            else:
                log(LogLevel.Debug, "Successful auth for {0}".format(user))
                return defer.succeed(user)
        except Exception as e:
            from traceback import print_exc

            print_exc(e)
Exemplo n.º 23
0
def test_net_accu(net, testloder):
    with torch.no_grad():
        test_iter = testloder.__iter__()
        i = test_iter.__next__()
        netout = net(i[0])
        test_loss = F.l1_loss(netout.view(-1), i[1])
    try:
        test_iter.__next__()
        log("testloader can still be loaded!")
        raise KeyBoardInterrupt
    except StopIteration:
        pass
    return test_loss
Exemplo n.º 24
0
def test_greed_play():
    cards = copy.copy(INIT_CARDS)
    cards.remove('S2')
    cards.remove('S3')
    random.shuffle(cards)
    cards_ll = [cards[0:12], cards[12:24], cards[24:37], cards[37:50]]
    for i in cards_ll:
        i.sort(key=cards_order)
    log(cards_ll)
    fmt_score_l = [[0, 0, False, False], [0, 0, False, False],
                   [0, 0, False, False], [0, 0, False, False]]
    s = Leaf.produce_1(['S2', 'S3'], cards_ll, 2, fmt_score_l)
    log(s.greed_play())
Exemplo n.º 25
0
 def complete_login(self):
     """
     This code is run when a character is successfully connected to.
     """
     self.my_state = State.LoggedIn
     log(LogLevel.Notice, "{0}#{1} connected from {2}".format(self.player.name, self.player.id, "<unknown>"))
     # Make them look around and check their inventory
     location = self.player.parent  # Get room that the player is in
     self.send_message(
         "Welcome, {0}! You are currently in: {1}\r\n{2}".format(
             self.player.name, location.name, location.get_desc_for(self.player)
         )
     )
     self.send_message("You are carrying: {0}".format(", ".join(map(lambda x: x.name, self.player.contents))))
Exemplo n.º 26
0
    def get_thing(self, obj):
        """
        Retrieves the Thing with the given database ID.

        Actually returns a ThingProxy that facilitates lazy-loading of Things and
        allows Things to be unloaded in the background to save memory, and transparently
        loaded again upon demand.
        """
        if not obj in self.cache:
            log(LogLevel.Trace, "Cache: MISS #{0}".format(obj))
            return self.ThingProxy(self, obj)
        else:
            log(LogLevel.Trace, "Cache: Hit #{0}".format(obj))
            return self.cache[obj]
Exemplo n.º 27
0
    def complete_login(self):
        """
        This code is run after a character is successfully connected to.

        When this function is called, the self.player object should already
        be initialized.
        """
        self.my_state = State.LoggedIn
        log(LogLevel.Notice, "{0}#{1} connected from {2}".format(self.player.name, self.player.id, '<unknown>'))
        self.send_message("To disconnect, type @quit")
        # Make them look around and check their inventory
        location = self.player.parent # Get room that the player is in
        self.send_message("Welcome, {0}! You are currently in: {1}\r\n{2}".format(self.player.name, location.name, location.get_desc_for(self.player)))
        self.send_message("You are carrying: {0}".format(', '.join(map(lambda x: x.name, self.player.contents))))
Exemplo n.º 28
0
    def player_login(self, username, password):
        """
        Verifies a player login. Returns -1 if login failed, or a database ID if successful.
        Password may be None to locate a player by username without verifying 
        """
        if not active:
            raise DatabaseNotConnected()

        log(
            LogLevel.Trace,
            "Verifying salted sha1 password hash for user {0}, password {1} (redacted)".format(
                username, "*" * len(password)
            ),
        )
        result = self._db_get_user(username)
        if not result:
            log(LogLevel.Trace, "No matching records in database")
            return -1
        pwhash, salt, obj = result
        log(
            LogLevel.Trace, "Successfully retrieved hash={0}, salt={1}, obj={2} from database".format(pwhash, salt, obj)
        )
        ret = obj if pwhash == self.hash_pass(password, salt.decode("hex_codec")) else -1
        if ret == -1:
            log(LogLevel.Debug, "Password hash mismatch for user {0}".format(username))
        return ret
Exemplo n.º 29
0
def test_with_c10():
    para_dir = "./NetPara20200715/"
    n0 = MrNN(room=0, place=0, name="n0")
    n0.prepare_net([(NN_First, para_dir + 'NN_First_11_121012.ckpt'),
                    (NN_Second, para_dir + 'NN_Second_9_126004.ckpt'),
                    (NN_Third, para_dir + 'NN_Third_7_130996.ckpt'),
                    (NN_Last, para_dir + 'NN_Last_5_135988.ckpt')])
    n0.cards_list = [
        'C3', 'CA', 'H2', 'H3', 'H4', 'H5', 'H6', 'H7', 'H8', 'H9', 'H10'
    ]
    n0.history = [(2, 'D3', 'D4', 'DJ', 'D6'), (1, 'S2', 'HJ', 'SQ', 'S5')]
    n0.cards_on_table = [2, 'C2', 'C10']
    n0.scores = [['DJ'], [], ['HJ'], ['SQ', 'HA', 'HQ', 'HK']]
    log(n0.pick_a_card())
Exemplo n.º 30
0
def manually_test(save_name):
    device_cpu=torch.device("cpu")
    pv_net=torch.load(save_name)
    pv_net.to(device_cpu)

    zt=MrZeroTree(room=255,place=3,name='zerotree3',pv_net=pv_net,device=device_cpu,train_mode=True)
    g=[MrGreed(room=255,place=i,name='greed%d'%(i)) for i in [0,1,2]]
    interface=OfflineInterface([g[0],g[1],g[2],zt],print_flag=True)

    interface.shuffle()
    for i,j in itertools.product(range(13),range(4)):
        interface.step()
        input()
    log(interface.clear())
    interface.prepare_new()
Exemplo n.º 31
0
 def dataReceived(self, data):
     "When data is received, process it according to state."
     if self.sshmode:
         # TODO: Is "sshmode" ever used now that everything is split out into SSHProtocol?
         self.transport.write(data)
         if data == '\r': self.transport.write('\n')
         data = data.translate('\r', '\n')
         # Split to completed lines
         lines = filter(len, data.split('\n')) # eliminate empty lines
         lines[0] = self.buf+lines[0]
         self.buf = lines[-1]
         for line in lines[:-1]: self.process_line(line.strip())
     else:
         log(LogLevel.Debug, "Received data without terminating newline, buffering: {0}".format(repr(data)))
         self.buf += data
Exemplo n.º 32
0
 def go(self, action):
     """Finds an action named action and executes it."""
     # TODO: Execute actions
     #actions = filter(lambda x: x.type is Action, self.parent.contents + self.contents)
     actions = [x for x in self.parent.contents + self.contents if x.type is Action]
     #TODO: Search order
     log(LogLevel.Trace, "Found actions: {0}".format(repr(actions)))
     if exit.startswith('#'):
         actions = [x for x in actions if exit[1:] == x.id()]
         #actions = filter(lambda x: exit[1:] == x.id(), actions)
     else:
         actions = [x for x in actions if x.name.lower.startswith(exit.lower)]
         #actions = filter(lambda x: x.name.lower().startswith(exit.lower()), actions)
     if not actions: return "You can't go that way."
     elif len(actions) > 1: return "I don't know which one you mean!"
Exemplo n.º 33
0
def example_SQ2():
    zt3 = MrZeroTree(room=255,
                     place=3,
                     name='zerotree3',
                     mcts_b=10,
                     mcts_k=2,
                     sample_b=-1,
                     sample_k=-2)

    zt3.cards_list = [
        "HQ", "HJ", "H8", "H7", "SA", "S3", "CJ", "C4", "CQ", "D3", "D10"
    ]
    zt3.cards_on_table = [2, "S6"]
    zt3.history = [[0, "S7", "SK", "S10", "S8"], [1, "C2", "C9", "C8", "C7"]]
    zt3.scores = [[], [], [], []]
    log(zt3.pick_a_card())
Exemplo n.º 34
0
 def purge_cache(self, expiry=3600): #TODO: Rename this function?
     """
     Remove from the cache all cached objects older than the given time.
     
     Save any objects that have been modified since they were cached.
     """
     threshold = int(time.time()) - expiry # Threshold is a time in the past
     cachesize = len(self.cache)
     #self.cache = [x for x in self.cache if x[1] > threshold]
     objects = self.live_set.copy()
     for obj in objects:
         if obj.cachetime < threshold:
             obj.unload() # Save and unload the object
         elif obj.dirty:
             obj.save()
     log(LogLevel.Trace, "Cache: Purged {0} stale objects from memory".format(len(objects)-len(self.live_set)))
Exemplo n.º 35
0
def benchmark(save_name, epoch, device_num, print_process=False):
    """
        benchmark raw network against MrGreed
        will be called by trainer
    """
    import itertools, numpy

    N1 = 512
    N2 = 2
    log("start benchmark against MrGreed for %dx%d" % (N1, N2))

    zt = [
        MrZeroTreeSimple(room=255,
                         place=i,
                         name='zerotree%d' % (i),
                         pv_net=save_name,
                         device="cuda:%d" % (device_num),
                         mcts_b=0,
                         mcts_k=1,
                         sample_b=BENCH_SMP_B,
                         sample_k=BENCH_SMP_K) for i in [0, 2]
    ]
    g = [MrGreed(room=255, place=i, name='greed%d' % (i)) for i in [1, 3]]
    interface = OfflineInterface([zt[0], g[0], zt[1], g[1]], print_flag=False)

    stats = []
    for k, l in itertools.product(range(N1), range(N2)):
        if l == 0:
            cards = interface.shuffle()
        else:
            cards = cards[39:52] + cards[0:39]
            interface.shuffle(cards=cards)
        for i, j in itertools.product(range(13), range(4)):
            interface.step()
        stats.append(interface.clear())
        interface.prepare_new()
        if print_process and l == N2 - 1:
            print("%4d" %
                  (sum([j[0] + j[2] - j[1] - j[3] for j in stats[-N2:]]) / N2),
                  end=" ",
                  flush=True)
    s_temp = [j[0] + j[2] - j[1] - j[3] for j in stats]
    s_temp = [sum(s_temp[i:i + N2]) / N2 for i in range(0, len(s_temp), N2)]
    log("benchmark at epoch %s's result: %.2f %.2f" %
        (epoch, numpy.mean(s_temp),
         numpy.sqrt(numpy.var(s_temp) / (len(s_temp) - 1))))
def test_gen_num_tables():
    s = ScenarioGen(0, [
        [0, 'S2', 'S3', 'S4', 'S5'],
        [0, 'S6', 'S7', 'S8', 'S9'],
        [0, 'S10', 'SJ', 'SQ', 'SK'],
        [0, 'H2', 'H3', 'H4', 'H5'],
        [0, 'H6', 'H7', 'H8', 'H9'],
        [0, 'H10', 'HJ', 'HQ', 'HK'],
        [0, 'C2', 'C3', 'C4', 'C5'],
        [0, 'C6', 'C7', 'C8', 'C9'],
        [0, 'C10', 'CJ', 'CQ', 'D7'],
    ], [0, 'SA', 'HA', 'D2'], ['D3', 'D4', 'D5', 'D6'],
                    number=10,
                    method=3)  #,method=1)
    for i in s:
        log(i)
        input()
Exemplo n.º 37
0
def benchmark():
    from MrRandom import MrRandom, Human
    from MrIf import MrIf
    from OfflineInterface import OfflineInterface
    g = [MrGreed(room=0, place=i, name='greed%d' % (i)) for i in range(4)]
    f = [MrIf(room=0, place=i, name="if%d" % (i)) for i in range(4)]
    r = [MrRandom(room=0, place=i, name="random%d" % (i)) for i in range(4)]
    rt = [
        MrRandTree(room=0, place=i, name='randtree%d' % (i)) for i in range(4)
    ]

    offlineinterface = OfflineInterface([f[0], g[1], f[2], g[3]],
                                        print_flag=False)
    N1 = 1024
    N2 = 2
    stats = []
    log("%s vs. %s for %dx%d" %
        (offlineinterface.players[0].family_name(),
         offlineinterface.players[1].family_name(), N1, N2))
    tik = time.time()
    for k, l in itertools.product(range(N1), range(N2)):
        if l == 0:
            cards = offlineinterface.shuffle()
        else:
            cards = cards[39:52] + cards[0:39]
            offlineinterface.shuffle(cards=cards)
        for i, j in itertools.product(range(13), range(4)):
            offlineinterface.step()
            """if i==7 and j==2:
                global print_level
                print_level=1
                offlineinterface.print_flag=True
                log("start outputs")"""
        stats.append(offlineinterface.clear())
        offlineinterface.prepare_new()
        if l == N2 - 1:
            print("%4d" %
                  (sum([j[0] + j[2] - j[1] - j[3] for j in stats[-N2:]]) / N2),
                  end=" ",
                  flush=True)
        #print("%s"%(stats[-1]),end=" ",flush=True)
    tok = time.time()
    log("time consume: %ds" % (tok - tik))
    for i in range(4):
        s_temp = [j[i] for j in stats]
        log("%dth player: %.2f %.2f" % (
            i,
            numpy.mean(s_temp),
            numpy.sqrt(numpy.var(s_temp) / (len(s_temp) - 1)),
        ),
            l=2)
    s_temp = [j[0] + j[2] - j[1] - j[3] for j in stats]
    log("%.2f %.2f" %
        (numpy.mean(s_temp), numpy.sqrt(numpy.var(s_temp) /
                                        (len(s_temp) - 1))))
Exemplo n.º 38
0
    def load_object(self, world, obj):
        """
        Loads and returns an object out of the database.
        """
        if not active:
            raise DatabaseNotConnected()

        result = self._db_load_object(obj)
        try:
            obtype = DBType(result[0])
        except IndexError as e:
            raise ValueError("Unknown DBType {0} while loading #{1} from the database!".format(result[0], obj))

        log(LogLevel.Debug, "We loaded {1}#{0} (type={2}) out of the database!".format(result[1], obj, obtype))

        newobj = Thing_of_type(obtype)(world, obj, *result[1:])

        log(LogLevel.Debug, "Database.load_object(): Returning {0}".format(repr(newobj)))
        return newobj
Exemplo n.º 39
0
    def __init__(self):
        # Sanity check sqlite version 3.6.19 or greater
        v = sqlite3.sqlite_version_info
        if(v[0] < 3 or (v[0] == 3 and (v[1] < 6 or v[1] == 6 and v[2] < 19) ) ):
            log(LogLevel.Warn, "Sqlite backend needs a newer version of Sqlite.")
            log(LogLevel.Warn, "You have: Sqlite {0[0]}.{0[1]}.{0[2]}".format(v))
            log(LogLevel.Warn, "You need: Sqlite 3.6.19 or later")
            log(LogLevel.Warn, "Continuing anyway, but foreign key constraints will not work.")

        log(LogLevel.Info, "Opening sqlite database connection.")

        self.conn = sqlite3.connect('world.db')
        self.active = True
        c = self.conn.cursor()
        c.execute('PRAGMA foreign_keys = ON')
        
        self._db_create_schema(c)
        c.close()
        self.conn.commit()
Exemplo n.º 40
0
 def gameend(self):
     # self.players_information looks like [['Sun', True, False], ['Miss.if0', True, True], ['Miss.if1', True, True], ['Miss.if2', True, True]] #?
     self.res.append(self.scores_num[self.place])
     should_record = True
     for i in range(self.place):
         if self.players_information[i][2]:
             should_record = False
             break
     if should_record:
         log("I, %s, should record." % (self.name))
         s = "\n".join(
             [", ".join([str(i) for i in trick]) for trick in self.history])
         s += '\nresult: %s\n\n' % (", ".join(
             [str(n) for n in self.scores_num]))
         fname = [pl[0] for pl in self.players_information]
         fname = "Records/" + "Records_" + "_".join(fname) + ".txt"
         log("writing to %s:\n%s" % (fname, s))
         with open(fname, 'a') as f:
             f.write(s)
Exemplo n.º 41
0
def test_last():
    g0=MrGreed(room=0,place=0,name="if0")
    #红桃就是躲
    g0.cards_list=['H3','H7','HJ','HA']
    g0.cards_on_table=[1, 'HQ', 'H8', 'H2']
    #羊要给队友
    #g0.cards_list=['D2','D7','DJ','S5','S8','S10']
    #g0.cards_on_table=[1, 'D8', 'DA', 'HJ']
    #不能把猪给队友
    #g0.cards_list=['D2','D7','DQ','S5','S8','SQ']
    #g0.cards_on_table=[1, 'S8', 'SA', 'S2']
    #有 好东西/坏东西 要 拿到/避开
    #g0.cards_list=['D2','D7','DQ','S5','S7','S10']
    #g0.cards_on_table=[1, 'S8', 'S2', 'DJ']
    #不得猪的情况下尽可能出大的
    #g0.cards_list=['D2','D7','DQ','S5','S8','S10']
    #g0.cards_on_table=[1, 'S8', 'SJ', 'S2']
    #无药可救时出大的
    #g0.cards_list=['D2','D7','DQ','S5','S8','S10']
    #g0.cards_on_table=[1, 'S8', 'SQ', 'S2']
    log(g0.pick_a_card())
Exemplo n.º 42
0
def test_accu(NetClass, FileName, order):
    net = NetClass()
    log(net)
    net.load_state_dict(torch.load(FileName))
    testdata = []
    parse_data("./Greed_batch/Greed_batch1.txt", testdata, order, max_num=128)
    testloder = torch.utils.data.DataLoader(testdata, batch_size=len(testdata))
    with torch.no_grad():
        test_iter = testloder.__iter__()
        i = test_iter.__next__()
        log("data size: %s" % (i[0].size(), ))
        netout = net(i[0])
        test_loss = loss_func_mul(netout, i[2], i[1])
        test_corr = correct_num(netout, i[2], i[1]) / len(i[2])
        try:
            test_iter.__next__()
            log("testloader can still be loaded!")
            raise KeyBoardInterrupt
        except StopIteration:
            log("testloader indeed stoped")
    log("%f %f" % (test_loss, test_corr))
Exemplo n.º 43
0
def example_SQ():
    zt3 = MrZeroTree(room=255,
                     place=3,
                     name='zerotree3',
                     mcts_b=10,
                     mcts_k=2,
                     sample_b=-1,
                     sample_k=-2)

    zt3.cards_list = [
        "HQ", "HJ", "H8", "H7", "SA", "S6", "S5", "S4", "S3", "CQ", "CJ", "D3"
    ]
    zt3.cards_on_table = [1, "S7", "SJ"]
    zt3.history = [
        [1, "C9", "C7", "C4", "H9"],
    ]
    zt3.scores = [[], ["H9"], [], []]
    """cards_dict=MrGreed.gen_cards_dict(zt3.cards_list)
    legal_choice=MrGreed.gen_legal_choice("S",cards_dict,zt3.cards_list)
    zt3.select_interact_cards(legal_choice)"""
    cards_played, scores_stage, void_info_stage = zt3.public_info()
    log(cards_played)
    for i in range(6):
        log("after stage %d: %s\n%s" %
            (i, scores_stage[i], void_info_stage[i]),
            end="")
        input()
    return
    log(zt3.pick_a_card())
Exemplo n.º 44
0
 def cmd_connect(self, params):
     """
     This command allows a user to log in as a particular character.
     This can be used when not logged in, but requires a password to do so.
     """
     log(LogLevel.Debug, "Received connect command from {0}".format(self.transport.getHost().host))
     if self.my_state > State.New:
         # Already connected
         self.send_message("You are already connected.")
         return
     if len(params) < 2:
         self.send_message("You must provide both a character name and a password.")
         return
     user = params[0]
     passwd = params[1]
     # Try and auth to an account
     self.player = self.world.connect(user, passwd)
     if self.player:
         self.complete_login()
     else:
         self.send_message("Your login failed. Try again.")
     return
Exemplo n.º 45
0
    def init_session(self, mode='Train'):
        log('initializing the model...')
        log('train_mode: %s' % mode)
        self.saver = tf.train.Saver()
        config = tf.ConfigProto()
        config.gpu_options.allow_growth = True
        config.log_device_placement = False  #: 是否打印设备分配日志
        config.allow_soft_placement = True  # : 如果你指定的设备不存在,允许TF自动分配设备
        self.sess = tf.Session(config=config)

        # check from checkpoint
        ckpt_path = self.config.checkpoint_path
        log('check the checkpoint_path : %s' % ckpt_path)
        ckpt = tf.train.get_checkpoint_state(ckpt_path)
        if ckpt and ckpt.model_checkpoint_path:
            log('restoring from %s' % ckpt.model_checkpoint_path)
            self.saver.restore(self.sess, ckpt.model_checkpoint_path)
        elif mode != 'Train':
            raise FileNotFoundError('Inference mode asks the checkpoint !')
        else:
            log('does not find the checkpoint, use fresh parameters')
            self.sess.run(tf.global_variables_initializer())
Exemplo n.º 46
0
def benchmark(handsfile, print_process=False):
    from MrGreed import MrGreed
    from MrZeroTree import MrZeroTree
    from OfflineInterface import OfflineInterface, read_std_hands, play_a_test
    import torch, inspect

    log_source(inspect.getsource(MrZeroTree.decide_rect_necessity))
    #log_source(inspect.getsource(MrZeroTree.possi_rectify_pvnet))

    zt0 = [
        MrZeroTree(room=255,
                   place=i,
                   name='zerotree%d' % (i),
                   mcts_b=10,
                   mcts_k=2,
                   sample_b=-1,
                   sample_k=-2) for i in [0, 2]
    ]
    team1 = [MrGreed(room=255, place=i, name='greed%d' % (i)) for i in [1, 3]]
    interface = OfflineInterface([zt0[0], team1[0], zt0[1], team1[1]],
                                 print_flag=False)

    if interface.players[0].family_name().startswith("MrZeroTree"):
        p0 = interface.players[0]
        log("mcts_b/k: %d/%d, sample_b/k: %d/%d" %
            (p0.mcts_b, p0.mcts_k, p0.sample_b, p0.sample_k))

    hands = read_std_hands(handsfile)
    N1 = len(hands)
    N2 = 2
    log("%s for %dx%d on %s" % (interface, N1, N2, zt0[0].device))
    stats = []
    for k, hand in hands:
        stats.append(play_a_test(interface, hand, N2))
        print("%4d" % (stats[-1], ), end=" ", flush=True)
        if (k + 1) % (N1 // 4) == 0:
            bench_stat(stats, N2)
    bench_stat(stats, N2)
Exemplo n.º 47
0
    def __init__(self, world, obj, name, flags,
            parent_id, owner_id, link_id, money,
            created, modified, lastused):

        # Keep a reference to the world instance
        self.world = world

        # Set up properties cache
        self._propcache = {}
        self._propdirty = set()

        # Set basic params
        self._obj, self.name, self.flags, self.money = (obj, name, flags, money)
        self._created, self._modified, self._lastused = (created, modified, lastused) ###

        # Precache our description
        self._propcache['_/desc'] = world.db.get_property(obj, '_/desc')

        self.owner = world.get_thing(owner_id)
        self.parent = world.get_thing(parent_id)
        self.link = world.get_thing(link_id) if link_id is not None else None

        log(LogLevel.Trace, 'A new Thing was instantiated with (ID:{0}) (name:{1}) (parentID:{2})'.format(self._obj, self.name, self.parent.id))
Exemplo n.º 48
0
 def connectionLost(self, data):
     if self.my_state < State.LoggedIn:
         pass
         log(LogLevel.Info, "{0} lost connection: {1}".format(self.host, data.getErrorMessage()))
     else:
         try: 
             log(LogLevel.Info, "{0}#{1} [{2}] lost connection: {3}".format(self.player.name, self.player.id, self.host, data.getErrorMessage()))
         except:
             log(LogLevel.Info, "<UNKNOWN> {0} lost connection: {1}".format(self.host, data.getErrorMessage()))
Exemplo n.º 49
0
def main():
    from MrZeroTreeSimple import BETA,MCTS_EXPL,BENCH_SMP_B,BENCH_SMP_K
    from MrZ_NETs import VALUE_RENORMAL
    log("BETA: %.2f, VALUE_RENORMAL: %d, MCTS_EXPL: %d, BENCH_SMP_B: %d, BENCH_SMP_K: %.1f"\
        %(BETA,VALUE_RENORMAL,MCTS_EXPL,BENCH_SMP_B,BENCH_SMP_K))

    from MrZ_NETs import PV_NET_2
    dev_train=0
    start_from=None # or a path to netpara file

    pv_net=PV_NET_2()
    log("init pv_net: %s"%(pv_net))
    if start_from==None:
        log("start from: zero")
    else:
        pv_net.load_state_dict(torch.load(start_from))
        log("start_from: %s"%(start_from))
    train(pv_net,dev_train_num=dev_train,dev_bench_num=1)
Exemplo n.º 50
0
def main():

    import World
    log(LogLevel.Notice, 'Initializing world...')
    world = World.getWorld() # Note: Currently, World is a singleton
    #world.db.db_get_user('admin')

    log(LogLevel.Debug, "Setting up ServerFactory")
    factory = protocol.ServerFactory()
    factory.protocol = BasicUserSession
    reactor.listenTCP(8888, factory)

    reactor.listenTCP(8822, SSHFactoryFactory(world))
    log(LogLevel.Notice, 'Now listening for connections.')
    log(LogLevel.Debug, 'Launching reactor.run() main loop')

    def onShutdown():
        log(LogLevel.Notice, "Shutting down...")
        world.close()

    reactor.addSystemEventTrigger('before', 'shutdown', onShutdown)
    reactor.run()
Exemplo n.º 51
0
 def __init__(self, *params):
     Thing.__init__(self, *params)
     log(LogLevel.Debug, 'A new Player object was instantiated!')
Exemplo n.º 52
0
 def onShutdown():
     log(LogLevel.Notice, "Shutting down...")
     world.close()
Exemplo n.º 53
0
def SSHFactoryFactory(world):
    """
    Creates and returns a factory class that produces SSH sessions.

    This function is responsible for loading the SSH host keys that our
    SSH server will use, or generating them if they do not exist (if possible).

    The reason why we have a double-factory setup is twofold:
    
    First, we need to dynamically load (or maybe generate) SSH host keys, and for
    some reason, Twisted's SSHFactory seems to require the SSH keys to be present
    as class attributes. The connection and userauth classes to use also need to
    be set this way.

    Second, this allows us to create a separate SSHFactory per world, should we ever
    run more than one world on a single server.
    """

    import os, sys
    from twisted.python.procutils import which
    if not os.path.exists('host_rsa'):
        if not sys.platform.startswith('linux'):
            log(LogLevel.Error, "SSH host keys are missing and I don't know how to generate them on this platform")
            log(LogLevel.Warn, 'Please generate the files "host_rsa" and "host_rsa.pub" for me.')
            raise SystemExit(1)
        log(LogLevel.Warn, 'SSH host keys are missing, invoking ssh-keygen to generate them')
        paths = which('ssh-keygen')
        if len(paths) == 0:
            log(LogLevel.Error, 'Could not find ssh-keygen on this system.')
            log(LogLevel.Warn, 'Please generate the files "host_rsa" and "host_rsa.pub" for me.')
            raise SystemExit(1)
        ret = os.spawnl(os.P_WAIT, paths[0], 'ssh-keygen', '-q', '-t', 'rsa', '-f', 'host_rsa', '-P', '', '-C', 'textgame-server')
        if ret != 0:
            log(LogLevel.Error, 'Failed generating SSH host keys. Is ssh-keygen installed on this system?')
            raise SystemExit(1)
        else:
            log(LogLevel.Info, 'Successfully generated SSH host keys')
            
    publicKey = file('host_rsa.pub', 'r').read()
    privateKey = file('host_rsa', 'r').read()

    # Global ban list shared by all factories.
    banlist = []

    from textgame.db import Credentials
    from twisted.cred.portal import Portal
    class SSHFactory(conch_factory.SSHFactory):
        """
        Factory responsible for generating SSHSessions.

        This SSHFactory is functionally identical to the built-in Conch
        SSHFactory, but is pre-configured with our SSH host keys.

        We also configure the SSHFactory with the services we are providing.
        In this case we are using our UserAuthService (a subclass of the
        built-in Conch SSHUserAuthServer) to authenticate users, and the
        built-in SSHConnection class to handle incoming connections.
        The built-in classes are configured via the
        Portal that is stored in the portal attribute.
        """
        publicKeys = {
                'ssh-rsa': keys.Key.fromString(data=publicKey)
                }
        privateKeys = {
                'ssh-rsa': keys.Key.fromString(data=privateKey)
                }
        services = {
                'ssh-userauth': UserAuthService,
                'ssh-connection': connection.SSHConnection
                }

        # We should really be getting this motd from the world instance
        bannerText = "HERE BE DRAGONS!\nThis software is highly experimental." + \
        "Try not to break it.\nDebug logging is enabled. DO NOT enter any real passwords!\n"

        # This Portal is the conduit through which we authenticate users.
        # The SSHRealm will generate user instances after auth succeeds.
        portal = Portal(SSHRealm(world), [
            # This checker allows the Portal to verify passwords.
            Credentials.CredentialsChecker(world.db),
            # This checker allows the Portal to verify SSH keys.
            SSHPublicKeyChecker(
                Credentials.AuthorizedKeystore(world.db)),
            # This "checker" will create a new user, instead of
            # authenticating an existing one.
            #Database.NewUserCreator(world.db)
        ])

        def buildProtocol(self, addr):
            # Reject this connection if the IP is banned.
            if addr.host in banlist:
                log.info("Rejecting connection from banned IP {0}".format(addr.host))
                return None
            # otherwise all good; let superclass do the rest
            log.info("Incoming SSH connection from {0}".format(addr.host))
            return conch_factory.SSHFactory.buildProtocol(self, addr)

        def banHost(self, host, duration=None):
            """
            Bans a host from connecting.
            """
            #TODO: Timed bans?
            log.info("Banning IP {0}".format(host))
            banlist.append(host)

    return SSHFactory()
Exemplo n.º 54
0
    def process_line(self, line):
        """
        Processes a line of input from the user.
        """

        if line == "":
            return
        words = line.split()
        cmd = words[0]
        params = words[1:] if len(words) > 1 else []

        # Are we logged in?
        if self.my_state < State.LoggedIn:
            # Only prelogin commands may be used
            if words[0] in prelogincmds:
                commands[words[0]](self, params)
            else:
                self.send_message("You're not connected to a character.")
            return

        # Code execution only proceeds beyond this point on a logged in character.
        # Commands are checked in the following order:
        # 1. Special prefixes (including @commands and the "say and :pose builtins)
        # 2. Matching actions (in order: player, room, objects in room, and then parent rooms)
        # 3. Builtin commands that do not have a special prefix

        # Builtin say command
        if line[0] == '"':
            # Echo back to the player
            self.send_message('You say, "{0}"'.format(line[1:]))
            # Send message to others who can hear it
            # TODO: Insert code here
            return
        # pose command
        if line[0] == ":":
            # Echo back to the player
            self.send_message("{0} {1}".format(self.player.name, line[1:]))
            # Send message to others who can see it
            # TODO: Insert code here
            return

        # If input begins with @, skip looking for actions (an action should never
        # begin with a @ character). Otherwise...
        if line[0] != "@":
            # Start the search at the player
            thing = self.player
            while True:
                log(LogLevel.Trace, "Searching {0} for {1}".format(thing.name, words[0]))
                # Retrieve a list of Actions contained by this thing, which match the word entered
                actions = [
                    x for x in thing.contents if x.type is Things.Action and x.name.lower().startswith(words[0].lower())
                ]
                log(LogLevel.Trace, "{0} contains {1}, matching: {2}".format(thing, thing.contents, actions))

                # Process list, and return if actions were found
                if self.process_action_list(actions):
                    return

                log(LogLevel.Trace, "Searching {0}'s contents for {1}".format(thing.name, words[0]))
                # Retrieve a list of Items contained by this thing, and look for Actions on them
                actions = reduce(
                    lambda x, y: x + y,
                    [
                        [
                            action
                            for action in item.contents
                            if action.type is Things.Action and action.name.lower().startswith(words[0].lower())
                        ]
                        for item in thing.contents
                        if item.type is Things.Item
                    ],
                    [],
                )
                log(LogLevel.Trace, "{0}'s contents contain matching: {1}".format(thing, actions))

                # Process list, and return if actions were found
                if self.process_action_list(actions):
                    return

                # Move to this Thing's parent and keep searching, unless we reached Room #0
                # in which case we are at the root of the parent tree and we give up.
                if thing.id == 0:
                    break
                else:
                    thing = thing.parent

        # Command dispatch map. Most commands should be accessed this way.
        if words[0] in commands.keys():
            try:
                log(
                    LogLevel.Debug,
                    "{0} running command: {1}{2}".format(
                        "{0}#{1}".format(self.player.name, self.player.id)
                        if self.player
                        else self.transport.getHost().host,
                        words[0],
                        "({0})".format(", ".join(params) if (words[0] not in ("connect", "@connect")) else "[redacted]")
                        if params
                        else "",
                    ),
                )
            except TypeError, e:
                log(LogLevel.Trace, "words: {0}, params: {1}".format(repr(words), repr(params)))
                log(LogLevel.Trace, "Exception: {0}".format(repr(e)))
            commands[words[0]](self, params)
            return
Exemplo n.º 55
0
    def _db_create_schema(self, cursor=None):
        """
        Create tables as required.
        """

        c = cursor if cursor else self.conn.cursor()

        # Obtain list of tables
        c.execute("""SELECT name FROM sqlite_master WHERE type='table'""")
        tables = [str(x[0]) for x in c.fetchall()]
        log(LogLevel.Debug, repr(tables))

        # The "meta" table is a simple key-value table that stores metadata about the database.
        if 'meta' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS meta (
    -- Stores metadata about the database, such as schema version number.
    -- This data is stored as simple key-value pairs.

    key TEXT PRIMARY KEY ASC,   -- Key name
    value NONE                  -- Value, can be any type
)
                    """)
            c.execute("""INSERT INTO meta VALUES ('schema_version', 0)""")
            log(LogLevel.Info, '- Created meta table.')

        # This table stores basic data about an object.
        # Extended data is stored in a separate table. This is done in order to
        # make it faster to do basic queries about an object.
        if 'objects' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS objects (
    -- This table stores basic data about an object.
    -- Extended data is stored in other tables, or as properties.
    -- This should make it faster to perform basic queries on an object.

    id INTEGER PRIMARY KEY ASC,       -- Primary database ID of this object (alias to built in rowid column)
    name TEXT NOT NULL,               -- Name of the object
    type INTEGER NOT NULL,            -- Type of the object (Room=0, Player=1, Item=2, Action=3, Script=4)
    flags INTEGER NOT NULL,           -- Bitfield of object flags
    parent INTEGER NOT NULL,          -- ID of the parent object (i.e. location) of this object
    owner INTEGER NOT NULL,           -- ID of owner of this object
    link INTEGER DEFAULT NULL,        -- Link to another object (home, or action). Null if unlinked.
    money INTEGER DEFAULT 0 NOT NULL, -- Amount of currency that this object contains
                                      -- The following timestamps are in unix time:
    created INTEGER DEFAULT (strftime('%s','now')),  -- Time of creation
    modified INTEGER DEFAULT (strftime('%s','now')), -- Time last modified in any way
    lastused INTEGER DEFAULT (strftime('%s','now')), -- Time last used (without modifying it)
    desc TEXT,                        -- Object description - this field is deprecated

    FOREIGN KEY(parent) REFERENCES objects(id),
    FOREIGN KEY(owner) REFERENCES objects(id),
    FOREIGN KEY(link) REFERENCES objects(id),

    -- Enforce the four possible types of object.
    CHECK( type >= 0 AND type <= 4 )
)
                    """)
            log(LogLevel.Info, '- Created objects table.')
            c.execute("""CREATE INDEX IF NOT EXISTS parent_index ON objects(parent)
    -- Contents of an object is determined by finding all objects whose parent is the container.""")
            c.execute("""CREATE INDEX IF NOT EXISTS owner_index ON objects(owner)
    -- Allow looking up or filtering objects by owner.""")
            c.execute("""CREATE INDEX IF NOT EXISTS link_index ON objects(link)
    -- Allow looking up or filtering objects by link - is this needed?""")

            # Create Room #0 (Universe) and Player #1 (Creator)
            # Initially create "The Universe" as owning itself, due to constraints
            now = time.time()

            #     id  name           typ flg par own link  $  cre. mod. used desc
            t = [(0, 'The Universe',  0,  0,  0,  0, None, 0, now, now, now, None), # desc fields here are now deprecated
                 (1, 'The Creator',   1,  0,  0,  1, None, 0, now, now, now, None),
                 # Other test objects
                 (2, 'no tea',        2,  0,  1,  1,  1,   0, now, now, now, None),
                 (3, 'west',          3,  0,  0,  1,  0,   0, now, now, now, None),
                 (4, 'drink',         3,  0,  2,  1,  0,   0, now, now, now, None),
                ]
            c.executemany("""INSERT INTO objects VALUES(?,?, ?,?,?,?,?, ?, ?,?,?, ?)""", t)
            # Set Room #0's owner as God
            c.execute("""UPDATE objects SET owner=1 WHERE id=0""")
            log(LogLevel.Info, '-- Created initial database objects.')

        # Create users table if it does not exist
        if 'users' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS users (
    -- Stores login information about user accounts.

    username TEXT PRIMARY KEY,  -- Username (is primary key)
    password TEXT,              -- Password hash (hexadecimal)
    salt TEXT,                  -- Salt used in hash (hexadecimal)
    email TEXT,                 -- Email address
    obj INTEGER,                -- Character reference
    -- Note: In future, the "obj" field will be removed and a separate table
    -- created which allows each account to have multiple characters associated.

    FOREIGN KEY(obj) REFERENCES objects(id)
)
                    """)

            log(LogLevel.Info, '- Created users table.')
            # Create admin user
            pwhash, salt = self.create_hash('admin')
            t = ('admin', pwhash, salt, 'admin@localhost', 1)
            c.execute("""INSERT INTO users VALUES (?, ?, ?, ?, ?)""", t)
            log(LogLevel.Info, '-- Created admin user.')

        #TODO: Obliterate messages table in favor of using properties
        # Stores extended data about an object, currently comprised of the following data:
        # - Object's long-form description (
#        if 'messages' not in tables:
#            c.execute("""CREATE TABLE IF NOT EXISTS messages (
#                    obj INTEGER,                  -- ID of object
#                    succ TEXT,                    -- Success message
#                    fail TEXT,                    -- Failure message
#                    osucc TEXT,                   -- External success message
#                    ofail TEXT,                   -- External failure message
#                    'drop' TEXT,                  -- Message when item is dropped or exit "drops" a player
#                    FOREIGN KEY(obj) REFERENCES objects(id)
#                    )""")
#            t = [(0, None, None, None, None, None),
#                 (1, None, None, None, None, None),
#                 (2, None, None, None, None, None),
#                 (3, "Life is peaceful there...", "The way is closed.", None, None, None)]
#            c.executemany("""INSERT INTO messages VALUES (?, ?, ?, ?, ?, ?)""", t)
#            log(LogLevel.Info, '- Created messages table.')

        # Table for storing arbitrary 'properties' about an object.
        if 'props' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS props (
    -- Stores arbitrary properties about an object.
    -- This is essentially a set of key/value pairs associated with an object.
    -- Each row holds a single key/value pair.
    -- At a database level, key names are arbitrary, but the server uses a
    -- directory structure maintained using a naming convention for the keys.

    obj INTEGER,        -- ID of object
    key TEXT,           -- Name of this property
    value TEXT,         -- Value of this property

    FOREIGN KEY(obj) REFERENCES objects(id)
)
                    """)
            # Index by id and key, unique index to ensure an id-key pairing cannot exist twice.
            c.execute("""
CREATE UNIQUE INDEX IF NOT EXISTS key_index ON props(
    obj, key -- Properties are uniquely indexed by id-key pairing.
    -- This constraint ensures that an object cannot have the same key twice,
    -- which ensures our INSERT OR REPLACE statement will work correctly.
)
                    """)

            # Assign sample property values to our starting objects.
            t=[ (0, '_/desc', "You can't hear anything, see anything, smell anything, feel anything, or taste anything, and you do not even know where you are or who you are or how you got here."),
                (1, '_/desc', "The being that you see cannot be described."),
                (2, '_/desc', "You really wish you had a cup of tea right about now."),
                (3, '_/desc', "There's nothing exciting in that direction."),
                (3, '_/succ', "Life is peaceful there..."),
                (3, '_/fail', "The way is closed."),
                (4, '_/fail', "You can't drink tea that you don't have."),
              ]
            c.executemany("""INSERT INTO props VALUES (?, ?, ?)""", t)
            log(LogLevel.Info, '- Created props table.')


        # Contains a list of IDs whose objects have been marked as deleted.
        # When a user requests deletion of an object, it is flagged as deleted,
        # and its ID is added to this table. This gives users a chance to undo.
        # When a new object is created, the first ID in this table (if any) is
        # removed and claimed as the ID of the new object.
        # The details of the deleted object with that ID are then overwritten
        # with those of the new object, and the old object is lost forever.
        # This system allows IDs to be reused and doesn't leave "holes" in the database.
        if 'deleted' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS deleted (
    -- This single-column table allows objects to be marked as deleted.
    -- This allows ID values to be reused.
    -- It also potentially allows recycled objects to be recovered.

    obj INTEGER, -- The ID of a deleted object

    FOREIGN KEY(obj) REFERENCES object(id)
)
                    """)
            log(LogLevel.Info, '- Created deleted IDs table.')

        # Many-to-many table for locks
        if 'locks' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS locks (
    -- This many-to-many table contains basic locks for objects.

    obj INTEGER,  -- ID of the object.
    lock INTEGER, -- ID of an object that has a lock on this object.

    FOREIGN KEY(obj) REFERENCES objects(id),
    FOREIGN KEY(lock) REFERENCES objects(id)
)
                    """)
            log(LogLevel.Info, '- Created locks table.')

        # Many-to-many table for access control list entries
        if 'acl' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS acl (
    -- This many-to-many table contains Access Control List entries.

    obj INTEGER,     -- ID of the object to which access is being controlled.
    player INTEGER,  -- ID of a player object which has some degree of access.
    flags INTEGER,   -- Flags which describe what degree of access is allowed.

    FOREIGN KEY(obj) REFERENCES objects(id),
    FOREIGN KEY(player) REFERENCES objects(id)
)
                    """)
            log(LogLevel.Info, '- Created acl table.')

        if 'scripts' not in tables:
            c.execute("""
CREATE TABLE IF NOT EXISTS scripts (
    -- This table stores the executable content of scripts.

    obj INTEGER,    -- ID of script object
    type INTEGER,   -- Type of script (0=lua)
    script TEXT,    -- Script content

    FOREIGN KEY(obj) REFERENCES objects(id)
)
                    """)
            log(LogLevel.Info, '- Created scripts table.')

        if not cursor: c.close()
Exemplo n.º 56
0
 def contents(self):
     """Retrieves a list of objects contained in this object."""
     items = self.world.get_contents(self)
     log(LogLevel.Trace, "Obtained contents for {0}: {1}".format(repr(self), repr(items)))
     return items
Exemplo n.º 57
0
 def use(self, user):
     # NOTE: What does it mean to "use" an item? Is this item-defined? Check spec
     log(LogLevel.Trace, "{0} used {1}".format(user, self))
Exemplo n.º 58
0
def SSHFactoryFactory(world):
    """
    Creates and returns a factory class that produces SSH sessions.

    This function is responsible for loading the SSH host keys that our
    SSH server will use, or generating them if they do not exist (if possible).

    The reason why we have a double-factory setup is twofold:
    
    First, we need to dynamically load (or maybe generate) SSH host keys, and for
    some reason, Twisted's SSHFactory seems to require the SSH keys to be present
    as class attributes. The connection and userauth classes to use also need to
    be set this way.

    Second, this allows us to create a separate SSHFactory per world, should we ever
    """

    import os, sys
    from twisted.python.procutils import which
    if not os.path.exists('host_rsa'):
        if not sys.platform.startswith('linux'):
            log(LogLevel.Error, "SSH host keys are missing and I don't know how to generate them on this platform")
            log(LogLevel.Warn, 'Please generate the files "host_rsa" and "host_rsa.pub" for me.')
            raise SystemExit(1)
        log(LogLevel.Warn, 'SSH host keys are missing, invoking ssh-keygen to generate them')
        paths = which('ssh-keygen')
        if len(paths) == 0:
            log(LogLevel.Error, 'Could not find ssh-keygen on this system.')
            log(LogLevel.Warn, 'Please generate the files "host_rsa" and "host_rsa.pub" for me.')
            raise SystemExit(1)
        ret = os.spawnl(os.P_WAIT, paths[0], 'ssh-keygen', '-q', '-t', 'rsa', '-f', 'host_rsa', '-P', '', '-C', 'textgame-server')
        if ret != 0:
            log(LogLevel.Error, 'Failed generating SSH host keys. Is ssh-keygen installed on this system?')
            raise SystemExit(1)
        else:
            log(LogLevel.Info, 'Successfully generated SSH host keys')
            
    publicKey = file('host_rsa.pub', 'r').read()
    privateKey = file('host_rsa', 'r').read()

    import Database
    from twisted.cred.portal import Portal
    class SSHFactory(conch_factory.SSHFactory):
        """
        Factory responsible for generating SSHSessions.

        This SSHFactory is functionaly identical to the built-in Conch
        SSHFactory, but is pre-configured with our SSH host keys.

        We also configure the SSHFactory with the services we are providing.
        In this case we are using the built-in Conch SSHUserAuthServer to
        authenticate users, and the built-in SSHConnection class to handle
        incoming connections. These built-in classes are configured via the
        Portal that is stored in the portal attribute.
        """
        publicKeys = {
                'ssh-rsa': keys.Key.fromString(data=publicKey)
                }
        privateKeys = {
                'ssh-rsa': keys.Key.fromString(data=privateKey)
                }
        services = {
                'ssh-userauth': userauth.SSHUserAuthServer,
                'ssh-connection': connection.SSHConnection
                }
        # This Portal tells us how to authenticate users
        portal = Portal(SSHRealm(world), [Database.CredentialsChecker(world.db)])

    return SSHFactory()
Exemplo n.º 59
0
 def connectionMade(self):
     h = self.transport.getHost()
     log(LogLevel.Info, "Incoming connection from {0}".format(h))
Exemplo n.º 60
0
 def requestAvatar(self, avatarId, mind, *interfaces):
     if IConchUser in interfaces:
         return interfaces[0], SSHUser(self.world, avatarId), lambda: None
     else:
         log(LogLevel.Error, "SSHRealm: No supported interfaces")
         raise NotImplementedError("No supported interfaces found.")