Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/plugins/multi_player.py
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/multi_player.py')
-rwxr-xr-xplugins/multi_player.py552
1 files changed, 552 insertions, 0 deletions
diff --git a/plugins/multi_player.py b/plugins/multi_player.py
new file mode 100755
index 0000000..68acc63
--- /dev/null
+++ b/plugins/multi_player.py
@@ -0,0 +1,552 @@
+import pygame
+from pygame import *
+from layout import *
+from frontend import hex2rgb
+import threading
+import time
+import traceback
+
+__PLUGIN_NAME__ = 'multi player'
+#import single_player
+
+class Status:
+ """ edited by the hosts """
+
+ game_state = '0' # 0=open_before_game, 1=..?
+
+ status_line = 'statusline'
+ clients = []
+
+ class Client:
+ def __init__(self, name, status=''):
+ self.name = name
+ self.status = status
+
+ def set_status_line(self, s1, s2):
+ return True
+
+ def get_status_line(self):
+ self.status_line = "%s;;%s" % (self.game_state, self.get_user_names(";"))
+ return self.status_line
+
+ def get_user_names(self, split_str=';;'):
+ usernames = []
+ for c in self.clients:
+ usernames.append(c.name)
+ return split_str.join(usernames)
+
+ def add_user(self, user_name):
+ for c in self.clients:
+ if c.name.upper() == user_name.upper(): return False
+
+ new_client = self.Client(user_name)
+ self.clients.append(new_client)
+ return True
+
+ def del_user(self, user_name):
+ print "deleting user %s" % user_name
+ new_clients = []
+ for c in self.clients:
+ if c.name.upper() != user_name.upper():
+ new_clients.append(c)
+
+ self.clients = new_clients
+ return True
+
+
+def show_answer():
+ A.display_answer()
+
+def finished():
+ sf.refresh()
+ sf.add_text_item("You have finished this category!", (180, 80))
+ sf.add_text_item("Won: %i" % Q.count_won, (220, 120))
+ sf.add_text_item("Lost: %i" % Q.count_lost, (220, 160))
+ pygame.display.update()
+ ask_category(130)
+
+
+def startgame(db_cat_id):
+ print "* Starting Game, Category:", db_cat_id
+ print "** Loading Questions"
+
+ Q.count_won = 0
+ Q.count_won = 0
+ A.reset_points()
+
+ Q.load_questions(db_cat_id)
+ display_points()
+
+ sf.clear_text_items()
+ next_question(0)
+
+
+def ask_category(offset_y = 0, offset_x = 0, cat_id=0):
+ Q.load(__SERVICES__.locale.lang_id, __SERVICES__.locale.lang_name)
+
+# sf.clear_text_items()
+
+ i = 1
+ y = 110 + offset_y
+ x = 340 + offset_x
+
+ sf.add_text_item("Category:", (x,y))
+ y += 50
+ x += 50
+ sf.add_text_item('All', (x,y), game_host.set_category, 0, True)
+# global game_host
+ for q in Q.categories:
+ y += 50
+ sf.add_text_item("%s (%s)" % (q[1], q[2]), (x,y), game_host.set_category, q[0], True)
+ i += 1
+
+ display_points()
+
+def display_points():
+ format = TextFormat(None, 30)
+ max_q = len(Q.questions)
+
+# sf.display_tooltip("%i" % (Q.count_won), (480, 14), format)
+# sf.display_tooltip("%i" % Q.count_lost, (480, 42), format)
+
+ if max_q == 0:
+ sf.display_line(0, True)
+ sf.display_line(0, False)
+ else:
+ sf.display_line(100 * Q.count_won / max_q, True)
+ sf.display_line(100 * Q.count_lost / max_q, False)
+
+def click_on_next_question():
+ next_question(0)
+
+def next_question(params):
+ print "* Next Question"
+
+ # Select Category
+ if Q._cat_id == -1:
+ ask_category()
+ return 1
+
+
+ # Pick only locale language's categories
+ if Q.question_pick():
+ __SERVICES__.frontend.question_display(Q.question)
+ Q.in_question = True
+
+ pass
+ else:
+ # game / cat finished!
+ in_question = False
+ print "finished"
+ Q._cat_id = -1
+ finished()
+ pass
+
+def spot_found(params):
+ if Q.in_question:
+ print "found"
+ A.display_icon("found")
+ A.play_sound(1)
+ Q.in_question = False
+ Q.count_won += 1
+ display_points()
+ show_answer()
+
+def spot_not_found(params):
+ print params
+ if Q.in_question:
+ print "not found"
+ A.display_icon("not-found")
+ A.play_sound(0)
+ Q.in_question = False
+ Q.count_lost += 1
+ display_points()
+ show_answer()
+ return "ok"
+
+
+
+
+class getStatus(threading.Thread):
+ running = True
+
+ def set(self, client_talk, status_call_function, abort_function=None):
+ self.talk = client_talk
+ self.status_call_function = status_call_function
+ self.abort_function = abort_function
+ self.running = True
+
+ def run(self):
+ while self.running:
+ time.sleep(2)
+ try:
+ self.status = self.talk('get:status')
+ self.status_call_function(self.status)
+ except:
+ traceback.print_exc()
+ print "getstatus aborted"
+ self.running = False
+ if self.abort_function != None: self.abort_function()
+
+
+class waitForUsersToJoin(threading.Thread):
+ running = True
+ last_users = ''
+
+ def set(self, talk, waittext_id, textid_connectedto=None):
+ self.talk = talk
+ self.waittext_id = waittext_id
+ self.textid_connectedto = textid_connectedto
+
+ def display_server_quit(self):
+ self.running = False
+
+ def run(self):
+ format = TextFormat()
+ font = pygame.font.Font(None, format.size)
+ bg = pygame.Surface((560, 30))
+
+ while self.running:
+ time.sleep(2)
+
+ users = self.talk("get:userlist")
+ if users == False: return
+
+ self.users = users.split(";;")
+ users = users.replace(";;", ", ")
+
+ print self.users
+ print users
+
+ text = font.render("> %s" % users, 1, hex2rgb(format.color))
+ textpos = text.get_rect()
+
+ bg.fill(hex2rgb(Layout().background))
+ bg.blit(text, (0,0))
+ sf.display_surface(bg, (48, 610))
+
+ pygame.display.update((48, 610, 560, 30))
+
+class DrawTimer:
+ def __init__(self):
+ self.bg = pygame.Surface((100, 60))
+
+ def draw(self, time):
+ self.bg.fill(hex2rgb(Layout().Question.background))
+
+ format = TextFormat(None, 46, None)
+ font = pygame.font.Font(None, format.size)
+ text = font.render("%i sec" % time, 1, hex2rgb(format.color))
+
+ self.bg.blit(text, (0,0))
+ sf.display_surface(self.bg, (150, 440))
+ pygame.display.update()
+
+class MultiPlayerHost:
+ category = 0
+ game_time = 0
+ textid_timer = -1
+ status = Status()
+
+ def __init__(self, host, port):
+ self.host = host
+ self.port = port
+ self.socket = __import__("plugins/_quizsocket")
+
+ print "starting server"
+ self.server = self.socket.Server('', port, self.status)
+ self.server.start()
+
+ def close(self):
+ self.client.running = False
+ self.waituser.running = False
+ self.server.quit()
+
+ def update_status(self, params):
+ print params
+
+ def load(self):
+ print "Creating a new game"
+ sf.clear_question_frame(True)
+
+ # Display some text
+ format = TextFormat(None, 40)
+ sf.add_text_item("New Multiplayer Game", (340, 45), None, None, False, format)
+ waittext_id = sf.add_text_item("Waiting for users to join...", (40, 570))
+
+ # let's spawn our own client now
+ self.client = self.socket.Client(self.host, self.port, Layout().user_name)
+ self.client.start()
+
+ # Display "Waiting for users to join..."
+ self.waituser = waitForUsersToJoin()
+ self.waituser.set(self.client.talk, waittext_id, None)
+ self.waituser.start()
+
+ # Constantly Get Status Updates from the Host
+# self.getstatus = getStatus()
+# self.getstatus.set(self.Spawner.client_talk, self.update_status, self.abort_net)
+# self.getstatus.start()
+
+ # Display Start Button
+ format = TextFormat(None, None, Colors().green)
+ sf.add_text_item("Start", (Layout().Question.x + Layout().Question.width - 150, 570), None, None, True, format)
+
+ # Display Categories
+ ask_category()
+ self.set_category(0)
+ pygame.display.update()
+
+ self.hookid_click = sf.add_event_hook("onclick", self.click)
+
+
+ # Draw Timer Option
+ img, rect = sf.image_load("images/xclock.png")
+ sf.display_surface(img, (40, 400))
+ self.draw_timer = DrawTimer()
+ self.click_timer()
+
+
+ def click(self, params):
+ x, y = list(params)
+ if x > 40 and x < (40 + 96) and y > 400 and y < (400 + 96):
+ # Click on Clock
+ self.click_timer()
+
+ def click_timer(self):
+ if self.game_time == 30:
+ self.game_time = 10
+ elif self.game_time == 20:
+ self.game_time = 30
+ elif self.game_time == 10:
+ self.game_time = 20
+ elif self.game_time == 0:
+ self.game_time = 10
+
+# self.Spawner.master_set_status("time:%i" % self.game_time)
+ self.draw_timer.draw(self.game_time)
+
+ def set_category(self, param):
+ cat_id = int(param)
+ self.category = cat_id
+
+ cat_name = 'All'
+ if cat_id > 0:
+ q = "SELECT text FROM categories WHERE cat_id=%i AND lang_id=%s" % (cat_id, __SERVICES__.locale.lang_id)
+ res = __SERVICES__.db.query(q)
+ print res
+ cat_name = res[0][0]
+
+# self.Spawner.master_set_status(u"cat:%s" % cat_name)
+
+ bg = pygame.Surface((360, 30))
+ bg.fill(hex2rgb(Layout().background))
+
+ format = TextFormat()
+ font = pygame.font.Font(None, format.size)
+
+ text = font.render("%s" % cat_name, 1, hex2rgb(format.color))
+ bg.blit(text, (0,0))
+ sf.display_surface(bg, (480, 115))
+ pygame.display.update()
+
+class MultiPlayerClient:
+ connected = False
+ game_time = 0
+ cat_name = u''
+
+ socket = None
+ waittext_id = None
+
+ format = TextFormat()
+ font = pygame.font.Font(None, format.size)
+ bg = pygame.Surface((560, 30))
+
+ def __init__(self, host, port):
+ self.host = host
+ self.port = port
+ self.connected = False
+ if self.socket == None: self.socket = __import__("plugins/_quizsocket")
+
+ def close(self):
+ self.getstatus.running = False
+ self.client.close()
+ self.connected = False
+
+ def load(self):
+ print "Joining a multiplayer game"
+
+ sf.clear_question_frame(True)
+
+ format = TextFormat(None, 40)
+ sf.add_text_item("Joining a Multiplayer Game", (340, 45), None, None, False, format)
+ pygame.display.update()
+
+# print self.connected
+ if self.connected == False:
+ host = sf.ask("host")
+ sf.refresh()
+ print "host: ", host
+ self.host = host
+
+ if len(host) == 0:
+ return False
+
+# if host == "l": host = "localhost"
+ print "starting client"
+ textid_connectedto = sf.add_text_item("[connecting to %s]" % host, (340, 80))
+ self.textid_connectedto = textid_connectedto
+
+ self.client = self.socket.Client(self.host, self.port, Layout().user_name, self.nonet_function)
+ self.client.start()
+
+ self.getstatus = getStatus()
+ self.getstatus.set(self.client.talk, self.update_status, self.nonet_function)
+ self.getstatus.start()
+
+ def display_catname(self):
+ bg = pygame.Surface((300, 60))
+ bg.fill(hex2rgb(Layout().Question.background))
+
+ format = TextFormat(None, 40)
+ font = pygame.font.Font(None, format.size)
+ text = font.render("Category: %s" % self.cat_name, 1, hex2rgb(format.color))
+
+ bg.blit(text, (0,0))
+ sf.display_surface(bg, (350, 190))
+ pygame.display.update()
+
+ def update_status(self, params):
+ self.status = params
+ print "STATUS UPDATE:",params
+
+ if params == False or len(params) == 0 or params == None or params == "None":
+ self.close()
+ return
+
+ if self.connected == False:
+ self.connection_ok()
+
+ n = params.split(";;")
+
+ users = n[1].replace(";", ", ")
+
+ text = self.font.render("> %s" % users, 1, hex2rgb(self.format.color))
+ textpos = text.get_rect()
+
+ self.bg.fill(hex2rgb(Layout().background))
+ self.bg.blit(text, (0,0))
+ sf.display_surface(self.bg, (48, 610))
+
+ pygame.display.update((48, 610, 560, 30))
+ print params
+
+# for n in params:
+# m = n.split(":")
+# if m[0] == "time":
+# if int(m[1]) != self.game_time:
+# self.game_time = int(m[1])
+# self.draw_timer.draw(self.game_time)
+#
+# if m[0] == "cat":
+# if m[1] != self.cat_name:
+# self.cat_name = m[1]
+# self.display_catname()
+
+
+ def connection_ok(self):
+ self.connected = True
+ sf.del_text_item(self.textid_connectedto)
+
+ self.textid_connectedto = sf.add_text_item("[connected to %s]" % self.host, (340, 80))
+ self.waittext_id = sf.add_text_item("Waiting for users to join...", (40, 570))
+
+ pygame.display.update()
+
+ # Draw Timer Option
+ img, rect = sf.image_load("images/xclock.png")
+ sf.display_surface(img, (40, 400))
+ self.draw_timer = DrawTimer()
+
+ def nonet_function(self):
+ print "client net aborted, quitting MultiPlayer-Client"
+
+ self.running = False
+
+ if self.waittext_id != None: sf.del_text_item(self.waittext_id)
+ if self.textid_connectedto != None: sf.del_text_item(self.textid_connectedto)
+
+ sf.add_text_item("Server quit the game", (340, 84))
+
+ # clear player
+ bg = pygame.Surface((560, 30))
+ bg.fill(hex2rgb(Layout().background))
+ sf.display_surface(bg, (48, 610))
+ pygame.display.update()
+
+ self.close()
+
+ global game_client
+ game_client = None
+
+
+
+
+def click_create():
+ global game_client
+ global game_host
+
+ if game_client == None and game_host == None:
+ game_host = MultiPlayerHost("", Layout().port)
+ sf.clear_text_items(False)
+ game_host.load()
+
+
+def click_join():
+ global game_client
+ global game_host
+
+ if game_client == None and game_host == None:
+ game_client = ''
+ game_client = MultiPlayerClient("localhost", Layout().port)
+
+ sf.clear_text_items()
+
+ res = game_client.load()
+ if res == False:
+ game_client = None
+
+def load():
+ global sf
+ sf = __SERVICES__.frontend;
+
+ sp = __import__("plugins/single_player")
+ sp.sf = sf
+
+ global Q
+ Q = sp.Questions()
+
+ global A
+ A = sp.Answer()
+
+ global game_host
+ game_host = None
+
+ global game_client
+ game_client = None
+
+ sf.add_menu_dir('/multi-player', 'Multiplayer', 1)
+ sf.add_menu_item('/multi-player', 'Create Game', click_create, 1)
+ sf.add_menu_item('/multi-player', 'Join Game', click_join, 2)
+
+ __SERVICES__.add_service("next_question", next_question)
+ __SERVICES__.add_service("spot_found", spot_found)
+ __SERVICES__.add_service("spot_not_found", spot_not_found)
+
+def close():
+ global game_host
+ global game_client
+
+ if game_host != None: game_host.close()
+ if game_client != None: game_client.close()
+