Well, I feel awkward to have two posts so close to each other on the forums, but this is a different topic on the same project, so it didn’t feel right to just tag it on the other thread.
Now that I have learned TCP is the way to go for my game it appears that a threading system is going to need to be set up. I have never used threads to do anything productive, so I’m a novice at it when it gets complex. I have my code setup the way I want it in my server and I have threading done (to my knowledge) correctly.
Here is what I have: (not cleaned up or optimized)
import sys
sys.path.append('C:\Python32\Lib\site-packages')
import MySQLdb as mdb
import socketserver
import threading
import datetime
maxPly = 20
con = None
cur = None
plyTable = [ [ 0 for i in range(5) ] for j in range(maxPly) ]
curPly = 0
class MyTCPHandler(socketserver.BaseRequestHandler):
"""
The RequestHandler class for our server.
It is instantiated once per connection to the server, and must
override the handle() method to implement communication to the
client.
"""
def handle(self):
global curPly
global maxPly
global plyTable
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print("{} wrote:".format(self.client_address[0]))
print(self.data)
sent = str(self.data,'ascii').split(":")
if (sent[0] == "l"):
#login check
cur.execute("SELECT password, userid FROM `prototb` WHERE username = '"+sent[1]+"'")
passW = cur.fetchone()#get the password from the database
if (passW != None):#if the password doesnt exist the username is wrong
if (passW[0] == sent[2]):#check the correctness of the password
if (curPly < maxPly):#if the server is not over capacity
for i in range(maxPly):#add them to the player list
if (plyTable[i][3] == False):
plyTable[i][3] = True#players active
plyTable[i][1] = self.client_address[0]#players address
plyTable[i][2] = sent[1]#players username
plyTable[i][4] = passW[1]#players id
self.request.send(bytes("+:"+str(i), 'ascii'))#allow the request
print("sent: "+"+:"+str(i))
curPly+=1#add 1 to the player count
break
else:
self.request.send(bytes("ServerFull", 'ascii'))#tell that the server is full
else:
self.request.send(bytes("-", 'ascii'))#refuse entry (bad password)
else:
self.request.send(bytes("-", 'ascii'))#refuse entry (bad username)
elif (sent[0] == "m"):
print(sent[1])
cur.execute("SELECT `displayname`,`curmap`,`curpos`,`Inventory`,`abilities` FROM `prototb` WHERE `userid` = '"+str(plyTable[int(sent[1])][4])+"'")
info = cur.fetchone()#get the info from the database
infostr = ""
for i in range(5):
infostr += (info[i] +":")
self.request.send(bytes(infostr, 'ascii'))#send the info to the client
class ThreadClass(threading.Thread):
def run(self):
global cur
global con
now = datetime.datetime.now()
print("Server Base Running: %s"% now)
HOST, PORT = "localhost", 9001
print("0")
con = mdb.connect('localhost', 'root', 'toor', 'protodb');#login to the database
print("1")
cur = con.cursor()
print("2")
# Create the server, binding to localhost on port 9999
server = socketserver.TCPServer((HOST, PORT), MyTCPHandler)
print("3")
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
print("4")
server.serve_forever()
print("5")
if __name__ == "__main__":
t = ThreadClass()
t.start()
You will notice a bunch of prints that are in the run function in the ThreadClass. I did this because I noticed a odd phenomena in the code. When I run this code outside blender it works fine and I get the numbers 1-4 printed out, as expected.
EDIT**
Inside blender it doesn’t get past
print("Server Base Running: %s"% now)
If you put a print right under the above line, it won’t print. I have removed the time-stamp and still have the same problem.
-Note: After playing with it, it seems to be random where it stops, sometimes it gets to other numbers. So I think something is terminating it before it can finish.
I have never had code stop mid-stream before so I do not know how to debug/treat this.
Any insight is always welcomed.
P.S. My original plan was to use multiprocessing but I got weirder reactions when I tried to implement that. The code produced a great deal of errors and it opened up another blender-editor program, which when exited printed “Blender Game Ended” in the main file’s terminal. I laughed that off and decided threading is a more productive way to go.