def execute(self, player, message): message = message.split() try: target = message[1].capitalize() except IndexError: u.send(player.conn, "Tell who what?", player.key) return try: content = message[2] except IndexError: u.send(player.conn, "Tell them what?", player.key) return for p in self.playerList: try: if p.name.startswith(target): sentContent = f"[TELL] {player.name}: {content}" returnedContent = f"You tell {player.name}: {content}" u.send(p.conn, sentContent, p.key) u.send(player.conn, returnedContent, player.key) return except AttributeError: # Will always happen when the server tries to send to itself. continue u.send(player.conn, "Player not found", player.key) return
def execute(self, player, message): message = message.partition(" ")[2] room = rooms[player.location] self.cursor.execute("UPDATE rooms set name = %s WHERE id = %s", (message, player.location)) room.update(cursor) u.send(player.conn, "Successfully edited room name", player.key)
def die(self, rooms): rooms[self.location].broadcast( f"{self.name} falls to the ground, dead.", self) u.send(self.conn, f"You are dead!", key=self.key) u.leaveRoom(self, rooms[self.location], dead=True) u.enterRoom(self, rooms[1], None, True) self.health = self.maxHealth self.nonLethalDamage = 0
def execute(self, player, message): output = "Online Players\n-------------" for p in self.playerList: try: output += f"\n{p.name}, {p.race}" except AttributeError: # First entry in playerList is actually the server, which will cause an error continue u.send(player.conn, output, player.key)
def execute(self, player, message): room = self.rooms[player.location] message = message.partition(" ")[2] if message == "": u.send(player.conn, "What do you want to say?", player.key) return newMessage = f"{player.name} says '{message}'" room.broadcast(newMessage, player) u.send(player.conn, f"You say '{message}'", player.key)
def execute(self, player, message): message = message.partition(" ")[2] message = f"[CHAT] {player.name}: {message}" for recipient in self.playerList.values(): try: u.send(recipient.conn, message, recipient.key) except (TypeError, AttributeError): # Will always happen when the server tries to send to itself. continue
def broadcast( self, message, exceptPlayer=None, exceptOther=None ): #Send a message to all players in the room, optionally exclude up to two players for player in self.playerList: if player == exceptPlayer or player == exceptOther: continue else: u.send(player.conn, message, player.key)
def lookAtPlayer(viewer, target): if target.race[0] in "aeio": racial_article = "an" else: racial_article = "a" if target.inCombat: output = f"{target.name} is locked in battle against {target.target.name}\n" else: output = f"{target.name} is standing here.\n" output += f"{target.name} is {racial_article} {target.race}.\n" output += f"{target.name} is {target.healthCheck()}." u.send(viewer.conn, output, viewer.key)
def execute(self, player, message): try: confirmation = message.split()[1] if confirmation == "confirm": player.conn.close() # If room is safe, exit the player instantly. Otherwise, leave them loose. # Only way I can currently think of to cleanly remove the player from the game, unfortunately, is to set their AFK timer extremely high player.timer = 99999 return except IndexError: u.send(player.conn, "To quit, type 'quit confirm'", player.key) return
def execute(self, player, message): word = message.split()[0].lower() if u.checkForMultiMove(message) or word in ("north", "east", "south", "west", "up", "down"): self.commandList["move"].execute(player, message) return for key in self.commandList.keys(): if key.startswith(word): self.commandList[key].execute(player, message) return else: u.send(player.conn, "Do what? (Try typing 'help')", player.key)
def execute(self, player, message): try: message = message.lower() message = message.split() direction = message[1] target = message[2] except (AttributeError, TypeError, KeyError, IndexError): u.send(player.conn, "Invalid usage, try: 'link west 1' format instead.", player.key) return key = u.convertStringToRoomEnum(direction) if not key: u.send(player.conn, "Direction invalid", player.key) try: self.cursor.execute( "UPDATE rooms SET " + direction + " = %s WHERE id = %s", ( target, player.location, ), ) except: u.send(player.conn, "Invalid usage, try: 'link west 1' format instead.", player.key) return self.rooms[player.location].update(cursor) u.send(player.conn, "Successfully linked rooms")
def execute(self, player, message): message = message.split()[1].capitalize() targetFound = False selfFound = False # See if the name matches anyone in the room, other than themselves for p in self.rooms[player.location].playerList: if p.name.startswith(message): if player == p: selfFound = True continue target = p targetFound = True break if selfFound and not targetFound: u.send(player.conn, "You can't kill yourself.", player.key) return elif not targetFound: u.send(player.conn, "There's nobody by that name here.", player.key) return elif player.target == target: u.send(player.conn, "You're trying as hard as you can!", target.key) return # check if room is a valid location for combat, I guess? # # If they weren't already, both people are in combat now if not player.inCombat: player.initiativeTotal = player.initiativeBonus + random.randint( 1, 20) player.inCombat = True if not target.inCombat: target.initiativeTotal = target.initiativeBonus + random.randint( 1, 20) target.inCombat = True # Whoever issued the command should target the target (obviously), but the target may already have a target player.target = target if not target.target: target.target = player # It's possible the combatants were already engaged, but focusing different targets. Check that before adding to the opponent lists. if not target in player.opponents: player.opponents.append(target) if not player in target.opponents: target.opponents.append(player) # Tell the attacker, defender, and any bystanders, what's going on. u.send(player.conn, f"You attack {target.name}!", player.key) u.send(target.conn, f"{player.name} attacks you!", target.key) self.rooms[player.location].broadcast( f"{player.name} attacks {target.name}!", player, target)
def execute(self, player, message): room = self.rooms[player.location] message = message.split() try: d = message[1] name = " ".join(message[2:]) except KeyError: u.send(player.conn, "Incorrect usage, try: dig [n,e,s,w,u,d] New_Name", player.key) return desc = "Default description" west, east, south, north, up, down = 0, 0, 0, 0, 0, 0 if d == "east": west = room.db[u.REnum["ID"]] elif d == "west": east = room.db[u.REnum["ID"]] elif d == "north": south = room.db[u.REnum["ID"]] elif d == "south": north = room.db[u.REnum["ID"]] elif d == "down": up = room.db[u.REnum["ID"]] elif d == "up": down = room.db[u.REnum["ID"]] else: u.send(player.conn, "Invalid direction, try: dig [n,e,s,w,u,d] New_Name", player.key) return # Save the room as the newest entry in the room table self.cursor.execute( "INSERT INTO rooms (name, east, west, north, south, up, down, description) VALUES (%s, %s, %s, %s, %s, %s, %s, %s)", (name, east, west, north, south, up, down, desc), ) # Now get the ID of the newest room self.cursor.execute("SELECT MAX(id) FROM rooms") newID = self.cursor.fetchone() # Use that ID to download the room from the database and add it to the rooms dict self.cursor.execute("SELECT * FROM rooms WHERE id = %s", (newID)) self.rooms[newID[0]] = r.Room(self.cursor.fetchone()) # Set the appropriate direction in the previous room to connect to this new room self.cursor.execute( "UPDATE rooms SET " + d + " = %s WHERE id = %s", (newID[0], room.db[u.REnum["ID"]]), ) # Update the origin room to reflect the new link room.update(self.cursor)
def die(self, rooms): rooms[self.location].broadcast( f"{self.name} falls to the ground, dead.", self) # TODO: Make this take into account that some levels are worth more than others - e.g fighter > warrior split = len(opponents) encounterRating = len(self.levels) + self.levelAdjustment for e in opponents: effectiveEnemyLevel = len(e.levels) + e.levelAdjustment xp += (300 * effectiveEnemyLevel * 2**( (encounterRating - effectiveEnemyLevel) * 0.5)) / split e.xp += xp try: u.send(e.conn, f"You are awarded {xp} xp.", e.key) except AttributeError: # If this opponent was a mob, it doesn't have a connection or a key pass u.leaveRoom(self, rooms[self.location], dead=True)
def execute(self, player, message): print(self.rooms.keys()) try: target = int(message.split()[1]) target = self.rooms[target] except KeyError: u.send(player.conn, f"Room {target} does not exist", player.key) return except (IndexError, ValueError): u.send( player.conn, "Please provide a target room. Correct format: 'tele 1'", player.key, ) return u.leaveRoom(player, self.rooms[player.location]) u.enterRoom(player, target) self.look.execute(player, "")
def execute(self, player, messsage): if player.race[0] in "aeio": racial_article = "an" else: racial_article = "a" # The name and race output = f"You are {player.name}, {racial_article} {player.race}.\n" # level/class? # Health output += f"Hitpoints: {player.health}/{player.maxHealth}." # Attributes for attr in player.attributes.keys(): output += f"\n {attr}: {player.attributesTotal[attr]}" # Saves # Skills # Other stuff? # send u.send(player.conn, output, player.key)
def execute(self, player, message): room = self.rooms[player.location] try: arg = message.split()[1] for p in room.playerList: if p.name.startswith(arg.capitalize()): lookAtPlayer(player, p) return if arg == "self": lookAtPlayer(player, player) except IndexError: # Triggered by message only containing one word, just means doing a default look pass try: key = u.convertStringToRoomEnum(arg) room = rooms[room.db[key]] except KeyError: # Triggered by rooms when room.db[key] is None, which means there is no room that way. Inform the player. u.send(player.conn, "There is nothing that way.", player.key) return except TypeError: pass # Type error will be triggered if key = None, which means arg was an unlisted direction. Just do a default look. except UnboundLocalError: pass # Triggered by trying to access arg for conversion, means there was no argument. Do a default look. directions = [] players = [] for x in range(2, 8): if room.db[x]: directions.append(u.REnumGet(x)) message = "\n".join(( room.db[u.REnum["NAME"]], room.db[u.REnum["DESCRIPTION"]], )) for p in room.playerList: if p.name == player.name: continue message += f"\n{p.name} is standing here." message += "\nValid directions: " + ",".join(directions) u.send(player.conn, message, player.key)
def execute(self, player, message): message = message.split() # Check if the player has specified a class try: self.cursor.execute("SELECT * FROM classes WHERE name = %s", (message[1], )) except IndexError: u.send(player.conn, "Gain a level in which class?", player.key) return #Check if the chosen class is real c = self.cursor.fetchone() if not c: u.send( player.conn, "Class not found, try 'help classes' for a full list of valid choices", player.key) return # Check if the player typed 'confirm' try: if not message[2] == "confirm": u.send(player.conn, f"Type 'level {c[0]} confirm' to level", player.key) return except IndexError: u.send(player.conn, f"Type 'level {c[0]} confirm' to level", player.key) return # Check if the player has enough xp (or hasn't chosen a starting class yet) lvl = len(player.levels) xpReq = (lvl * (lvl - 1) * s.XP_CONSTANT) - (lvl - 1 * (lvl - 2) * s.XP_CONSTANT) if lvl == 0 or player.xp >= xpReq: print("level up") # TODO: apply all benefits of class in a function on the player, or something else: u.send( player.conn, f"XP requirements not met, you need {xpReq - player.xp} more.", player.key) return
def post(request): response = RequestResponse() if check_params(request.POST, ['name', 'username', 'password', 'email', 'phone']): post_data = request.POST if Writer.objects.filter(email=post_data['email']).exists() or \ Writer.objects.filter(username=post_data['username']).exists(): response.set_status(400) response.set_message('User already registered') else: user = Writer() user.username = post_data['username'] user.name = post_data['name'] user.email = post_data['email'] user.phone = post_data['phone'] user.password = Writer.encrypt_password(post_data['password']) user.save() four_digit_code = random4() new_validation = EmailValidation(writer=user, code=four_digit_code) new_validation.save() try: email_subject = 'Welcome to the Wall!' link = 'http://' + request.META['HTTP_HOST'] + '/api/activate/?email=' + \ user.email + '&auth=' + four_digit_code email_body = "Hi %s,\rwelcome to the wall. Your activation code is %s.\r\r" \ "Or you can directly activate your account by clicking here: %s" \ % (user.name, four_digit_code, link) send(user.name, user.email, email_subject, email_body) except KeyError: data = {'activation_code': four_digit_code} response.set_data(data) response.set_status(200) response.set_message('User successfully added') else: response.set_status(400) response.set_message('Incorrect Parameters') return Response(response.respond())
def execute(self, player, message): # Calculate direction to go in options = [] for index, direction in enumerate(range(2, 8)): if self.rooms[player.location].db[direction]: options.append( (self.rooms[player.location].db[direction], index)) if not options: # In the unlikely(?) event the player is trapped in a room with no exits u.send(player.conn, "There is nowhere to flee.", player.key) return if player.inCombat: # Check whether the attempt to flee is going to be successful success = random.randint(0, 1) else: success = True # Leave the room, end combat and unlock targets if success: direction = random.choice(options) u.leaveRoom(player, self.rooms[player.location], u.REnumGet(direction[1]), True) u.enterRoom(player, self.rooms[direction[0]], u.REnumGet(u.reverseDirection(direction[1]))) self.look.execute(player, "") if player.target: u.send( player.conn, f"You successfully escaped {player.target.name}", player.key, ) elif player.inCombat: u.send(player.conn, "You successfully escaped.", player.key) else: u.send(player.conn, "You successfully 'escaped'.", player.key) else: u.send(player.conn, "You fail to get away!", player.key) return
def execute(self, player, message): if player.inCombat: u.send(player.conn, "You can't just walk out of combat!", player.key) return multi = u.checkForMultiMove(message) if multi: # message will be, for example, 'eeeswdu' for c in message: d = u.lengthenDirection(c) # take 'e' and make it 'east' try: destination = self.rooms[self.rooms[player.location].db[ u.convertStringToRoomEnum( d )]] # convert east to the appropriate enum key for the database except KeyError: u.send(player.conn, "There's nothing that way", player.key) continue u.leaveRoom( player, self.rooms[player.location], d ) # Inform the room and its players that the player is departing u.enterRoom( player, destination, u.REnumGet(u.reverseDirection( u.convertStringToRoomEnum(d))), ) # convert east to the enum key, then flip it to west's enum key and convert it back to west self.look.execute(player, "") else: # message will be, for example, 'east' try: destination = self.rooms[self.rooms[player.location].db[ u.convertStringToRoomEnum( message)]] # turn east to an enum key for the database except KeyError: u.send(player.conn, "There's nothing that way", player.key) return u.leaveRoom(player, self.rooms[player.location], message) u.enterRoom( player, destination, u.REnumGet( u.reverseDirection(u.convertStringToRoomEnum(message))), ) # convert east to an enum key, then reverse it self.look.execute(player, "")
def verification(msg, player): verification = player[1] connection = player[0] # If player[1] is a list, this will work and progress through authentication. If it is not, it will except # Ver[4] will be the AES key if verification[4] == None: verification[4] = msg print("Received and stored AES key") u.send(connection, "Please select a username:"******"SELECT name FROM players WHERE name = %s;", (verification[0], )) result = cursor.fetchone() if result: print("Asking player to select password") u.send(connection, "Please enter your password:"******"Please select a password:"******"Please select a name with only English letters, maximum 30 characters\n", verification[4], ) verification[2] = 1 verification[0] = 0 elif ( verification[1] == 0 ): # Player is either setting or entering password, depending on verification[2] m = hashlib.sha256() m.update(bytes(msg, "utf-8")) msg = m.hexdigest() if verification[2] == 1: cursor.execute("SELECT password FROM players WHERE name = %s;", (verification[0], )) playerPassword = cursor.fetchone() if playerPassword[0] == msg: u.send(connection, "Welcome to the server.", verification[4]) verification[1] = 1 else: u.send(connection, "Password incorrect, re-enter username", verification[4]) return [0, 0, 1, 0] else: verification[1] = msg u.send(connection, "Please re-enter to confirm", key=verification[4]) elif verification[ 2] == 0: # Player is confirming the previously entered password m = hashlib.sha256() m.update(bytes(msg, "utf-8")) msg = m.hexdigest() if msg == verification[1]: u.send(connection, "Welcome to the server.", key=verification[4]) verification[2] = 1 else: u.send( connection, "Password mismatch, clearing both. Try again.", key=verification[4], ) verification[1] = 0 return verification
def attack(self, rooms): try: # e.g BAB 1: 1//5 = 0 + 1 = 1 # e.g BAB 6: 6//5 = 1 + 1 = 2 attackCount = self.baseAttackBonus // 5 + 1 except ZeroDivisionError: # e.g BAB 0: 0//5 = ZD error attackCount = 1 currentBaseAttackBonus = self.baseAttackBonus # dualWielding will be bool the player can choose to toggle - it decides whether to attack with your offhand item. # Player may turn off dW for e.g holding a torch, holding a shield # if self.offhand and self.dualWielding: # currentBaseAttackBonus -= 6 # attackCount += 1 # if self.offhand.light: # currentBaseAttackBonus += 2 # if 'Two-Weapon Fighting' in self.feats: # currentBaseAttackBonus += 2 for a in range(attackCount): # if a == attackCount-1 and self.offhand and self.dualWielding and not 'Two-Weapon Fighting' in self.feats: # If it's the final attack in a dual wielding flurry and the player doesn't have TWF feats, modify the cBAB further # currentBaseAttackBonus -=4 # also use off-hand weapon for this attack instead of regular roll = random.randint(1, 20) # TODO: Pre-calculate all attribute modifiers somewhere, then make sure they stay updated rollTotal = (roll + currentBaseAttackBonus + (self.attributesTotal["strength"] // 2 - 5) + self.size) damageTotal = 0 if (rollTotal > self.target.armourClass + (self.target.attributesTotal["dexterity"] // 2 - 5) + self.target.size): for key in self.damage.keys(): for die in range(self.damage[key]): damageTotal += random.randint(1, key) damageTotal += self.attributesTotal["strength"] // 2 - 5 u.send( self.conn, f"[{rollTotal},{damageTotal}] You hit {self.target.name} with your attack!", self.key, ) u.send( self.target.conn, f"[{rollTotal},{damageTotal}] {self.name} lands a blow against you!", self.target.key, ) rooms[self.location].broadcast( f"{self.name} lands a blow against {self.target.name}!", self, self.target, ) self.target.takeDamage(damageTotal, self.damageType, self, rooms) else: u.send( self.conn, f"[{rollTotal}] You miss {self.target.name} with your attack!", self.key, ) u.send( self.target.conn, f"[{rollTotal}] {self.name} misses you with their attack!", self.target.key, ) rooms[self.location].broadcast( f"{self.name} misses {self.target.name} with an attack!", self, self.target, ) # Each attack has 5 less BAB than the previous, e.g fighter level 6 can attack twice with BAB +6/+1 currentBaseAttackBonus -= 5 # Players with multiple attacks could easily end up killing their enemy in the middle of a flurry if not self.target: break
pass connections.pop(oldPlayer) foundPlayer = True connectedToExisting = True print( "Player is already logged in, connecting to existing body" ) rooms[connections[client].db[ PEnum.LOCATION.value]].broadcast( connections[client].name + "'s body has been taken over by a new soul.", connections[client], ) u.send( connections[client].conn, "You have entered your body, forcing out the soul inhabiting it.", key=connections[client].key, ) break if (not foundPlayer): # If the player wasn't in the main list, check if they're in the loose player list for looseP in loosePlayers: if looseP.name == connections[client][0]: # Replace the old body's encryption key with the new one looseP.key = connections[client][4] # Replace the new connection's verification tuple with the old body connections[client] = looseP # Tell the old body about its new connection looseP.conn = (client) # Remove the body from loose players loosePlayers.remove(looseP)