[Python] Online-RPG: Server-Seite

Dieses Thema im Forum "Projekte / Codes" wurde erstellt von Kolazomai, 15. März 2006 .

Schlagworte:
  1. 15. März 2006
    Online-RPG: Server-Seite

    Hi,

    ich freue mich, dass es nun endlich eine Showcase-Unterteilung in dieser Section gibt. Danke an Raid-Rush!

    Ich mach jetzt mal den ersten und biete einen noch-nicht vollständigen Code eines Online-RPG-Servers.

    Der Server ist in Python geschrieben.

    Einiges zur Geschichte und Idee: Ich wusst mal wieder ned, was ich programmieren sollte. Dann hab ich bisschen rumgefragt und am Ende kam dann ein Projekt mit 2 anderen Leuten zusammen. Der eine schreibt den Windows-Clienten mit Visual Basic, der andere macht HP und entwickelt Ideen und Ich schreib die Serverseite. Das Spiel soll in Richtung D&D gehen, weiteres ist aber noch ned klar, also braucht keine Fragen zu stellen . Jeder, der will und ein etwas fortgeschrittenes Projekt angehen will, kann selbst seinen eigenen Clienten jetzt coden. Dazu müsst ihr nur meinen Code etwas interpretieren ( die Schlüsselwörter stehen alle als Commentare drin ) und schon braucht ihr nur noch Socket aufmachen, über port 1337 connecten ( Die IP gibts per PN bei mir ) und eure Funktionen nach Schlüsselwörter aufbauen.

    Zu diesem Code:
    An sich gefällt mir mein Source-Code, aber teilweise ist er etwas "unschön" mit den globals geraten. Und ich denke kaum, irgendjemand wird ihn auf das erste mal durchlesen gleich interpretieren können. Also habt ihr auch Zeit, etwas zu knobeln

    Ausserdem hoff ich, dass er jetzt reinpasst, weil er doch bisher gute 450 Zeilen hat und noch sehr viele dazukommen werden ( PvP = Player vs Player z.b. ). Dieser Code ist also kein vollständiger, sondern nur ein Stück und ich werde nach und nach ihn erweitern.

    Viel Spass beim interpretieren

    Für Fragen und Verbesserungsvorschläge steh ich offen ^^.

    Mfg,

    Kolazomai

    Code:
    Code:
    #!/usr/bin/python
    # Name des RPGs
    # Coded by Kolazomai
    # ICQ: 329-573-284
    # Published under GPL
    #####################################
    ### Name des RPGs ###
    #####################################
    
    print "###################################"
    print "### Name des RPGs ###"
    print "### Server Edition ###"
    print "###################################"
    print "Starting Server now ..."
    
    ### import ###
    import SocketServer,os
    from SocketServer import ThreadingTCPServer
    from time import gmtime, strftime,sleep
    ###
    
    
    
    
    
    
    ### Log ###
    logfile = "/home/cordel/Heldensagen.log"
    log = open(logfile,"w")
    ###
    
    
    
    
    
    ### Variables ###
    port = 1337 # port
    clients = {} # {ip:client,...}
    ips = [] # ips
    message_pot = {} # messages , i dont know whether i need it
    messages = [] # same
    group_all = [] # w00t
    message_all = "" # ...
    Login = False # ...
    gibts = False # ...
    locals_users = {"Heim":[],
     "Wald":[],
     "Gebirge":[],
     "Tropfsteinhoehle":[],
     "Vulkan":[],
     "Untoten-Gruft":[],
     "Verlassene Zwergenmine":[],
     "Troll-Lagerstaetten":[],
     "Hauptstadt Gut":[],
     "Hauptstadt Boese":[]} # {location:[name1,name2,name3],...}
    ###
    # This is a very powerful Variable
    # It will look like that:
    # {Name:{Name:<name>,Race:<race>,..},Name2:{...}}
    # I do have just to call
    # users_data[Name][<info>] and i get what i want
    users_data = {}
    # Values:
    # Name,Race,Level,Mana,current Mana,Hp,current Hp,
    # Staerke,Geschick,Avaibility,Location,Experience
    ###
    
    ######
    
    
    
    
    ### class Main ###
    class main_:
     def __init__(self):
     pass
    
    #
    
    
     def login(self,data):
     global Login
     login_data = data.split('!')
     ### Get User's Data ###
     self.users_data_file = open('/home/cordel/rpg/users/'
     +str(login_data[0])+'.txt','r')
     self.users_data = self.users_data_file.read()
     self.users_data = self.users_data.split('\n')
     self.users_data_file.close()
     ###
     if self.users_data[1] == login_data[1]:
     print_("Server: Login Correct :>")
     Login = True
     else:
     print_("Server: Login Incorrect!")
     Login = False
    
    #
    
     def new(self,data):
     global gibts
     self.x = data.split("!")
     try:
     #File exist?
     os.stat("/home/cordel/rpg/users/"
     +str(self.x[0])+".txt")
     gibts = True
     except OSError:
     # no it doesn't
     self.a = open("/home/cordel/rpg/users/"
     +str(self.x[0])+".txt","w")
     self.a.write(str(self.x[0])+'\n')#0.Name
     self.a.write(str(self.x[1])+'\n')#1.Pass
     self.a.write(str(self.x[2])+'\n')#2.Race
     self.a.write("1"+"\n")#3.Level
     self.a.write("80"+"\n")#4.Mana
     self.a.write("10"+"\n")#5.Staerke
     self.a.write("6"+"\n")#6.Geschick
     self.a.write("100"+"\n")#7.Leben , HP
     self.a.write("100"+"\n")#8.current HP
     self.a.write("80"+"\n")#9.current Mana
     self.a.write("0"+"\n")#10.current Experience
     self.a.close()
    
     
     # Add this player to all_players#
     all_players_file = file("/home/cordel/rpg/all_users.txt","a")
     all_players_file.write(str(self.x[0])+"\n")#Player's name
     all_players_file.close()
     #
    
    #
    
    
     def get_char_info(self,name,ip):
     global users_data
     self.users_data_file = open('/home/cordel/rpg/users/'
     +str(name)+'.txt','r')
     self.users_data = self.users_data_file.read()
     self.users_data = self.users_data.split('\n')
     self.users_data_file.close()
     ##############################################################
     # What i do now: #
     # there is users_data #
     # I will pick up the logined user #
     # and make a new dic for him #
     # {"Name":"Name",<datas>} #
     # So all_names will look like that: #
     # [<ip>:{"name":"Kolazomai","race":"Human",...},<ip>:{...}] #
     # then I only have to call users_data[client][<info>] #
     # and i get what i want #
     ##############################################################
     # Now i will try to fetch all character-infos #
     #
     #
     # Now i add it to my powerful users_data - variable
     users_data[name] = {"NAME":str(self.users_data[0]),
     "RACE":str(self.users_data[2]),
     "LEVEL":str(self.users_data[3]),
     "MANA":str(self.users_data[4]),
     "STAERKE":str(self.users_data[5]),
     "GESCHICK":str(self.users_data[6]),
     "LEBEN":str(self.users_data[7]),
     "CURRENT_LEBEN":str(self.users_data[8]),
     "CURRENT_MANA":str(self.users_data[9]),
     "LOCATION":"Heim",
     "AVAI":0, # short form of Avaibility
     "EXPERIENCE":str(self.users_data[10])}
    
    
     # puhh, hard job xD #
    
     
    
    ###
    
    
    ### def print_ ###
    def print_(it):
     log.write(str(it)+"\n")
     print it
    
    ###
    
    
    ### def Player Versus Player ###
    class pvp_:
     def __init__(self):
     pass
    
     # ------------------------------
    
     def start(self,datas,client):
     # datas = <cmd><opponent>
     
     # There are several pvp-commands
     
     if datas[0:3] == "atc":
     # Return Avaibility
     what_to_return = "pvpatc" # pvp + command
     what_to_return += users_data[datas[3:]]["AVAI"]
     what_to_return += "|" # final letter
     return what_to_return
    
     elif datas[0:3] == "dul":
     # Send Opp's-Charinfos
     what_to_return = pvp.get_char_info_opp(datas[3:])
     return clients[client]+"!pvpdul"+what_to_return
     
    
     # ------------------------------
    
     def get_char_info_opp(self,opp):
     print "Get the infos now ..."
     infos = users_data[opp]
     # Add the receiving Client's name
     what_datas = ""
     for x in infos.values():
     what_datas += str(x)
     what_datas += "!"
    
     # Now i got all infos
     what_datas += "|" # final letter
     return what_datas
    
    
    ###
    
    
    
    
    ### Setting the Server-Routine ###
    class handling(SocketServer.StreamRequestHandler):
     def handle(self):
     client,address = self.client_address
     print_(str(client)+" is here!")
     main = main_()
     active = True
     while active == True:
     data = self.request.recv(1000)
     if client in clients:
     print_(str(clients[client])+"["+str(client)+"]"+
     " said: "+str(data)
     +" ["
     +strftime("%a, %d %b %Y %H:%M:%S",gmtime())
     +"]")
     else:
     print_(str(client)+" said: "+str(data)
     +" ["
     +strftime("%a, %d %b %Y %H:%M:%S",gmtime())
     +"]")
     
     # I will proove, whether
     # data is a 0-byte-string
     # if yes, i close the connection
     if data == "" or data[0:4] == "quit":
     quit_()
     active = False
     break
    
    
    
     
     #################
     # Now I split data
     # It's like that:
     # %<cmd1>%<cmd2>%<cmd3>%<cmdN>
     # and get some dic
     # ***************************************
     # *ALL messages, being received and sent*
     # *will have a | at the end *
     # ***************************************
     
     data_split = data.split("|")
     
     # data_split looks like that:
     # ['','cmd1','cmd2','cmd3','cmdN']
     # I will remove Null-Strings
     # cause it only takes performance
     #################
     
     try:
     data_split.remove('')
     except:
     pass
     
     #################
     print data_split
     
     
    
     
     for data_ran in data_split:
     global message_pot,log,Login,ips,gibts,messages
     global group_all,message_all,users_data,locals_users
     
     if data_ran[0:3] == "log":
     #logUser!Pass!Race
     main.login(data_ran[3:])
     ips += ["127.0.0.1"]#
     main.get_char_info("Some_Player","127.0.0.1")#
     main.login("Some_Player!Some_Player!Mensch")#
     clients["127.0.0.1"] = "Some_Player"#
    
     if Login == True:
     aa = data_ran[3:].split("!")
     clients[client] = aa[0]
     print client,"is now also known as",clients[client]
     ips += [client]
     self.request.send(clients[client]+
     "!pra"+
     "Server: Login erfolgreich!|")
     main.get_char_info(clients[client],client)
     # Add this user to the Home-Location
     locals_users["Heim"].append(clients[client])
     Login = False # nur zur Sicherheit
    
    
     
     elif data_ran[0:3] == "msg":
     x = data_ran.split('!')
     #msg!empfaenger!absender!nachricht
     empfaenger = x[1]
     absender = x[2]
     nachricht = x[3]
     #<Empfaenger>!msg<Nachricht>!<Absender>
     if empfaenger in messages:
     self.request.send(str(absender)+"!"+"msg"
     +str(empfaenger)
     +"did not receive a previous msg yet"
     +"!Server|")
    
     
     elif empfaenger <> "all":
     #the message
     message_pot[empfaenger] = ( str(empfaenger)+"!"
     +"msg"+str(nachricht)+"!"
     +str(absender) )
     # add empfaenger to the list
     messages += [empfaenger]
    
     
     elif empfaenger == "all":
     # message to all
     # What i do now:
     # Add all online Users to group_all
     # Then create a message_all
     # If a user req now
     # I will proove,whether he is in group_all
     # if yes, i will sent him the message_all
     # and remove him from group_all
     # if no, nothing happens
     # The Problem is, that all guys have to req
     # till its possible again to send a generall msg
     if group_all == []:
     la = []
     for x in ips:
     la += [clients[x]]
     group_all += la
     message_all = ( str(empfaenger)+"!"
     +"msg"+str(nachricht)+"!"
     +str(absender) )
     else:
     self.request.send(str(absender)+"!"+"msg"
     +"Can't send a msg"
     +" to all at the moment"
     +"!Server|")
    
    
     
     elif data_ran[0:3] == "req":
     #req
     #for chat
     print "req"
     
     if clients[client] in messages:
     print message_pot
     #remove the empfaenger
     messages.remove(clients[client])
     #messagepop
     self.request.send(str
     (message_pot.pop
     (clients[client]))
     +"|")
    
     
     if clients[client] in group_all:
     self.request.send(message_all+"|")
     group_all.remove(clients[client])
    
     
     elif data_ran[0:3] == "new":
     #newUser!Pass!Race
     main.new(data_ran[3:])
     :mad:_you = data_ran[3:].split("!")
     # I should work with
     # if user in all_users.txt: ...
     if gibts == True:
     # Account existing allready
     # editieren ------> V V V V V V V V V V V V V V V
     self.request.send(str(:mad:_you[0])+"!praServer:"+
     " Account does allready exist!|")
     gibts = False
     else:
     self.request.send(str(:mad:_you[0])+"!praServer:"+
     " Neuer Benutzer angelegt!|")
    
    
     
     elif data_ran == "quit":
     quit_()
     # active = False will stop the while-statement
     # unfortunately he'll end it, before breaking
     active = False
     # Now i leave the for-statement
     break
    
    
    
     
     elif data_ran[0:3] == "onl":
     #onl
     #Send back who's online
     print "onl"
     send_it = "all!onlall!"
     for x in ips:
     if x <> client:
     send_it += str(clients[x])+"!" # returns the Names
     send_it += "$"
     self.request.send(send_it+"|")# send the data
    
    
     
     elif data_ran == "save_log":
     #Save the log and open it again!
     log.close()
     log = open(logfile,"a")
     quit_()
     break
    
    
    
    
    
     elif data_ran == "akt":
     #<Empfaenger>!akt<Level>!<Leben im moment>
     #!<Leben gesamt>!<Mana im Moment>!<Mana gesamt>
     #!<Geschicklichkeit>!<Staerke>!<Erfahrung>!$
     a = clients[client]
    
     self.request.send(str(clients[client])+"!"+
     "akt"+
     str(users_data[a]["LEVEL"])+"!"+
     str(users_data[a]["CURRENT_LEBEN"])+"!"+
     str(users_data[a]["LEBEN"])+"!"+
     str(users_data[a]["CURRENT_MANA"])+"!"+
     str(users_data[a]["MANA"])+"!"+
     str(users_data[a]["GESCHICK"])+"!"+
     str(users_data[a]["STAERKE"])+"!"+
     str(users_data[a]["EXPERIENCE"])+"!"+
     "$"+
     "|")
    
     
    
    
     elif data_ran[0:3] == "sav":
     #savName!Pass!Rasse
     #!Level!Mana!Staerke!
     #Geschick!Leben!Leben im moment!Mana im moment!
     #current Experience
     x = data_ran[3:].split("!")
     users_file_ = file("/home/cordel/rpg/users/"+
     str(clients[client])+".txt","w")
     users_file_.write(str(x[0])+"\n")#Name
     users_file_.write(str(x[1])+"\n")#Password
     users_file_.write(str(x[2])+"\n")#Rasse
     users_file_.write(str(x[3])+"\n")#Level
     users_file_.write(str(x[4])+"\n")#Mana
     users_file_.write(str(x[5])+"\n")#Staerke
     users_file_.write(str(x[6])+"\n")#Geschick
     users_file_.write(str(x[7])+"\n")#Leben
     users_file_.write(str(x[8])+"\n")#current leben
     users_file_.write(str(x[9])+"\n")#current mana
     users_file_.write(str(x[10])+"\n")#current Experience
     # lots of writing :o
     
     users_file_.close()
     main.get_char_info(clients[client],client)
    
    
    
     
     elif data_ran[0:3] == "ara":
     # ara = actualise place of residence
     # syntax: araLocality
     # example: araWood
     # ------------------
     # i send back: ( in 1 string )
     # <Empfaenger>!ara<Spielerinmeinemgebiet1(name)>?
     #<Spielerinmeimemgebiet1(verfuegbarkeit)!
     #<spielerinmeinemgebiet2(name)>?
     #<Spielerinmeimemgebiet2(verfuegbarkeit)!$
     # ---------------
     # Localities
     # Heim ::: 1 
     # Wald ::: 2 
     # Gebirge ::: 3 
     # Tropfsteinhoehle ::: 4 
     # Vulkan ::: 5 
     # Untoten-Gruft ::: 6 
     # Verlassene Zwergmine ::: 7 
     # Troll-Lagerstaetten ::: 8 
     # Hauptstadt Gut ::: 9 
     # Hauptstadt Boese ::: 10
     #########################
     x = data_ran[3:].split("!")
    
    
     # This is all users in the specified locality
     teh_clients = locals_users[x[0]]
     message_ara = (str(clients[client])+"!"+
     "ara")
     for x in range(len(teh_clients)):
     # I add to message_ara
     # the name of the boyz in the locations ( teh_clients )
     # and then the available key in the users_data
     if teh_clients[x] <> clients[client]:
     message_ara += (str(teh_clients[x])+"?"+
     str(users_data[teh_clients[x]]["AVAI"])+
     "!")
     
     message_ara += "Some_Player?0!$" # final letter :-)
    
     # Now send it ;-) #
     print message_ara
     self.request.send(message_ara+"|")
     
    
    
    
     elif data_ran[0:3] == "soa":
     # soa = *S*-tatus *O*-f *A*-vailability
     # 0 = available
     # 1 = not available
     users_data[clients[client]]["AVAI"] = int(data_ran[3])
    
    
    
    
     elif data_ran[0:3] == "apr":
     x = data_ran[3:].split("!")
     # aprNewLocation!OldLocation
     # user changes location
     try:
     # remove user of the location
     locals_users[x[1]].remove(clients[client])
     except:
     pass
     # add this user to the location
     locals_users[x[0]].append(clients[client])
    
     # change the users_data -variable
     users_data[clients[client]]["LOCATION"] = x[0]
     
    
    
     elif data_ran[0:3] == "pvp":
     # pvp<cmd><person>
    
     # Send pvp the datas
     what_to_send = pvp.start(data_ran[3:],client)
     # It will return, what i need
     self.request.send(what_to_send)
    
     print what_to_send
    
     else:
     print data_ran
     print "What the F***??"
     print "Wrong command oO"
    
    
     ###
     # Where is select case ;-) ? #
     # Bah, i should've written all in classes :S #
     # Damnit xD #
     ###
    
    
     # End of For :P
     print "/* EoF */"
     
    
    ###
    
    
    
    ### def quit_ ###
    def quit_():
     #.pop removes the name
     try:
     print_(str(clients.pop(client))+"["+str(client)+"]"+
     " left!")
     except:
     pass
     #remove the ip
     try:
     ips.remove(client)
     except:
     pass
     
     # remove him from Location
     try:
     locals_users[users_data[clients[client]]["LOCATION"]].remove(clients
     [client])
     except:
     pass
     try:
     del users_data[clients[client]]
     except:
     pass
     try:
     group_all.remove(clients[client])
     except:
     pass
    
    ###
    
    
    # Init pvp #
    pvp = pvp_()
    #
    
    
    
    ### Starting the Server ###
    server = ThreadingTCPServer(("",port), handling)
    server.serve_forever()
    ###
    
     
  2. Video Script

    Videos zum Themenbereich

    * gefundene Videos auf YouTube, anhand der Überschrift.