diff --git a/api.py b/api.py
deleted file mode 100644
index d152e65..0000000
--- a/api.py
+++ /dev/null
@@ -1,53 +0,0 @@
-from flask import Flask, redirect, url_for, render_template, session, request, copy_current_request_context, jsonify
-from datetime import timedelta
-import os
-from basegame import *
-
-
-import flask
-
-app = flask.Flask(__name__)
-app.config["DEBUG"] = True
-app.secret_key = "hi"
-playerNameList = []
-
-@app.route('/', methods=['GET'])
-def home():
- return "Login"
-
-@app.route('/playerlist', methods=['GET'])
-def playerlist():
- fuckyou = json.dumps(playerNameList)
- print(fuckyou)
- return fuckyou
-
-@app.route("/login", methods=["POST", "GET"])
-def login():
- if request.method == "POST":
- session.permanent = True # <--- makes the permanent session
- user = request.form["nm"]
- session["name"] = user
- playerNameList.append(user)
- return redirect(url_for("playerlist"))
- else:
- if "name" in session:
- return redirect(url_for("playerlist"))
-
- return render_template("login.html")
-
-@app.route("/user")
-def user():
- if "user" in session:
- user = session["user"]
- return f"
{user}
"
- else:
- return redirect(url_for("login"))
-
-@app.route("/logout")
-def logout():
- session.pop("user", None)
- return redirect(url_for("login"))
-
-
-
-app.run(debug=True, host='0.0.0.0')
diff --git a/client.py b/client.py
deleted file mode 100755
index 7e481d3..0000000
--- a/client.py
+++ /dev/null
@@ -1,436 +0,0 @@
-import wx
-import socket
-from common import *
-import glob
-
-
-class ClientVCKO(wx.App):
- def OnInit(self):
- self.connection_status = False
- self.player_id = ""
- self.player_name = ""
- self.lobby = []
- self.in_lobby = False
- self.in_game = False
- self.game_id = ""
- self.game = None
- self.debug_frame = DebugFrame(self)
- self.lobby_frame = LobbyFrame(self)
- self.game_frame = GameFrame(self)
- self.last_lobby_state = ""
- self.last_game_state = ""
- self.game_count = 0
- return True
-
- def parse_response(self, response):
- if len(response) > 1000:
- print(f"{response[:1000]}...")
- else:
- print(response)
- first_word = response.split()[0]
- full_command = response.split()
- match first_word:
- case "lobby":
- if full_command[1] == "joined" and len(full_command) == 3:
- self.player_id = full_command[2]
- self.in_lobby = True
- elif full_command[1] == "state":
- json_response = ' '.join(full_command[2:])
- new_lobby_state = json.loads(json_response)
- last_dict = new_lobby_state[-1] if new_lobby_state else None
- if last_dict and last_dict in new_lobby_state:
- new_lobby_state.remove(last_dict)
- self.lobby = new_lobby_state
- self.game_count = last_dict['game_count']
- else:
- print("Couldn't understand that response")
- case "game":
- if full_command[1] == "joined" and len(full_command) == 3:
- self.game_id = full_command[2]
- self.in_game = True
- self.in_lobby = False
- self.lobby_frame.enter_game()
- elif full_command[1] == "state":
- json_response = ' '.join(full_command[2:])
- new_game_state = json.loads(json_response)
- with open("game_state.txt", "w") as dump:
- dump.write(json.dumps(new_game_state, indent=4))
- if new_game_state == self.last_game_state:
- return
- self.last_game_state = new_game_state
- self.game_frame.update_board(self.last_game_state)
- def update_lobby_status(self):
- return self.in_lobby
-class TiledImages(wx.Window):
- def __init__(self, parent, image_path, rows=3, cols=3, overlap=10):
- super().__init__(parent)
- self.image = wx.Image(image_path)
- self.rows = rows
- self.cols = cols
- self.overlap = overlap
- self.SetMinSize(wx.Size(self.image.GetWidth() * self.cols - self.overlap, self.image.GetHeight() * self.rows - self.overlap))
-
- def OnPaint(self, event):
- dc = wx.PaintDC(self)
- for row in range(self.rows):
- for col in range(self.cols):
- x = col * (self.image.GetWidth() - self.overlap)
- y = row * (self.image.GetHeight() - self.overlap)
- dc.DrawBitmap(wx.Bitmap(self.image), x, y)
-
-
-class MonsterCard(wx.StaticBitmap):
- def __init__(self, parent, card_id):
- img_path = None
- for file in glob.glob(f"images/monster_{card_id:02d}*.jpg"):
- img_path = file
- break # Stop searching after the first matching file
- if not img_path:
- raise ValueError(f"No image found for card ID {card_id:02d}")
-
- self.parent = parent
- self.card_id = card_id
- self.bitmap = None
-
- super().__init__(parent, -1)
-
- self.Bind(wx.EVT_SIZE, self.on_size)
- self.update_bitmap()
-
- def update_bitmap(self):
- img_path = glob.glob(f"images/monster_{self.card_id:02d}*.jpg")[0]
- img = wx.Image(img_path, wx.BITMAP_TYPE_ANY)
- width, height = self.parent.GetSize()
- width = int(width * 0.15) # Set the width to 15% of the parent width
- height = int(width * img.GetHeight() / img.GetWidth()) # Scale height to maintain aspect ratio
- img = img.Scale(width, height, wx.IMAGE_QUALITY_HIGH)
- self.bitmap = wx.Bitmap(img)
- self.SetBitmap(self.bitmap)
-
- def on_size(self, event):
- self.update_bitmap()
- event.Skip()
-
-
-class GameFrame(wx.Frame):
- def __init__(self, app):
- super().__init__(parent=None, title='VCK Online', size=Constants.large_window_size)
- self.app = app
- self.panel = wx.Panel(self)
-
- # Create a static box sizer with padding
- self.vbox = wx.StaticBoxSizer(wx.StaticBox(self.panel, label=""), wx.VERTICAL)
- self.vbox.AddSpacer(10) # Add a bit of padding at the top
- self.monster_grid = wx.BoxSizer(wx.HORIZONTAL)
- # Create the game state list box
- self.game_state_list = wx.ListCtrl(self.panel, style=wx.LC_REPORT | wx.LC_SINGLE_SEL)
- self.vbox.Add(self.game_state_list, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
-
- self.vbox.AddSpacer(10) # Add a bit of padding at the bottom
-
- # Set the sizer for the panel
- self.panel.SetSizer(self.vbox)
-
- self.SetMinSize(Constants.medium_window_size)
- self.last_game_state = ""
- self.timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.get_game_status, self.timer)
- self.timer.Start(500)
- self.panel.Layout()
-
- def get_game_status(self, event=None):
- if self.app.in_game and connection_check():
- self.app.parse_response(send(f"game get_status {self.app.game_id}"))
- if self.last_game_state == self.app.last_game_state:
- # If the current game state is the same as the last one, don't update the list control
- return
- pretty_json_str = json.dumps(self.app.last_game_state, indent=4, sort_keys=False)
- self.game_state_list.ClearAll()
- self.game_state_list.InsertColumn(0, "Game State")
- for idx, state in enumerate(pretty_json_str.split('\n')):
- self.game_state_list.InsertItem(idx, state.strip())
- self.game_state_list.SetColumnWidth(0, wx.LIST_AUTOSIZE)
- # Save the new game state
- self.last_game_state = self.app.last_game_state
-
- def update_board(self, game_state):
- game = Game(game_state)
- monster_ids = []
- for index, monster_stack in enumerate(game.monster_grid):
- monster_stack_sizer = wx.BoxSizer(wx.VERTICAL) # Create a vertical sizer for the monster stack
- for monster in monster_stack:
- if monster['is_accessible']:
- card_id = monster['monster_id']
- try:
- img_path = glob.glob(f"images/monster_{card_id:02}*.jpg")[0]
- except IndexError:
- raise ValueError(f"No image found for card ID {card_id:02}")
- bitmap = wx.Bitmap(img_path, wx.BITMAP_TYPE_ANY)
- card = MonsterCard(self.panel, card_id)
- card.SetBitmap(bitmap)
- monster_stack_sizer.Add(card, 0, wx.BOTTOM, 10) # Add the card to the monster stack sizer
- monster_ids.append(monster['monster_id'])
- # Add the monster stack sizer to the monster grid sizer
- self.monster_grid.Add(monster_stack_sizer, 0, wx.LEFT | wx.RIGHT, 10)
- self.vbox.Add(self.monster_grid, proportion=1, flag=wx.EXPAND | wx.ALL, border=10)
- self.panel.Layout()
- self.panel.Refresh()
- self.Fit()
-
-class LobbyFrame(wx.Frame):
- def __init__(self, app):
- super().__init__(parent=None, title='VCK Online Lobby', size=Constants.medium_window_size)
- self.app = app
- self.panel = wx.Panel(self)
- self.vertical_sizer = wx.BoxSizer(wx.VERTICAL)
-
- splitter = wx.SplitterWindow(self.panel)
-
- left_panel = wx.Panel(splitter)
- left_sizer = wx.BoxSizer(wx.VERTICAL)
- status_sizer = wx.BoxSizer(wx.HORIZONTAL)
- text = wx.StaticText(left_panel, label='Enter name:')
- self.name_field = wx.TextCtrl(left_panel, style=wx.TE_PROCESS_ENTER, value='')
- self.connection_status_indicator = wx.StaticText(left_panel, label="Connection Status")
- submit_button = wx.Button(left_panel, label='Submit')
- submit_button.Bind(wx.EVT_BUTTON, self.on_submit)
- self.name_field.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter)
- status_sizer.Add(wx.StaticText(left_panel), 0, wx.EXPAND | wx.RIGHT, 5)
- status_sizer.Add(self.connection_status_indicator, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
- status_sizer.Add(wx.StaticText(left_panel), 0, wx.EXPAND | wx.LEFT, 5)
- left_sizer.Add(text, 0, wx.ALL, 5)
- left_sizer.Add(self.name_field, 0, wx.EXPAND | wx.ALL, 5)
- left_sizer.Add(submit_button, 0, wx.ALL | wx.CENTER, 5)
- left_sizer.AddStretchSpacer()
- left_sizer.Add(status_sizer, 0, wx.ALIGN_LEFT | wx.BOTTOM, 5)
- left_panel.SetSizer(left_sizer)
- self.last_lobby_state = []
- self.current_player_index = None
-
- # Create the list control and columns
- right_panel = wx.Panel(splitter)
- self.list_ctrl = wx.ListCtrl(right_panel, style=wx.LC_REPORT)
- self.list_ctrl.InsertColumn(0, "Player Name")
- self.list_ctrl.InsertColumn(1, "Ready Status", format=wx.LIST_FORMAT_RIGHT)
- self.set_connection_status()
- self.get_lobby_status()
- self.set_game_count()
-
- # Create the ready button
- ready_button = wx.Button(right_panel, label="Ready Up")
- ready_button.Bind(wx.EVT_BUTTON, self.on_ready_up)
-
- # Create the static text
- self.active_games_text = wx.StaticText(right_panel, label="Active games: 42069")
-
- # Add the static text and ready button to a horizontal box sizer
- button_sizer = wx.BoxSizer(wx.HORIZONTAL)
- button_sizer.Add(self.active_games_text, 0, wx.ALIGN_BOTTOM | wx.LEFT | wx.BOTTOM, 5)
- button_sizer.AddStretchSpacer()
- button_sizer.Add(ready_button, 0, wx.ALIGN_BOTTOM | wx.RIGHT | wx.BOTTOM, 5)
-
- # Add the list control and the button sizer to the vertical sizer
- right_sizer = wx.BoxSizer(wx.VERTICAL)
- right_sizer.Add(self.list_ctrl, 1, wx.ALL | wx.EXPAND, 5)
- right_sizer.Add(button_sizer, 0, wx.EXPAND, 5)
- right_panel.SetSizer(right_sizer)
-
- splitter.SplitVertically(left_panel, right_panel)
- splitter.SetMinimumPaneSize(250)
- splitter.SetSashGravity(0.0)
-
- self.vertical_sizer.Add(splitter, 1, wx.EXPAND)
- self.panel.SetSizer(self.vertical_sizer)
-
- self.SetMinSize(Constants.small_window_size)
-
- # Bind the size event to adjust the column widths
- self.Bind(wx.EVT_SIZE, self.on_size)
- self.Bind(wx.EVT_CLOSE, self.on_close)
-
- self.lobby_check_timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.get_lobby_status, self.lobby_check_timer)
- self.lobby_check_timer.Start(1000)
- # Create a timer to call the connection_check method every 2 seconds
- self.connection_check_timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.set_connection_status, self.connection_check_timer)
- self.connection_check_timer.Start(10000)
- self.Show()
-
- def set_connection_status(self, event=None):
- if connection_check():
- self.connection_status_indicator.SetLabel("Connected")
- self.connection_status_indicator.SetForegroundColour(Constants.green)
- else:
- self.connection_status_indicator.SetLabel("Not Connected")
- self.connection_status_indicator.SetForegroundColour(Constants.red)
-
- def set_game_count(self):
- try:
- self.active_games_text.SetLabel(f"Active games: {self.app.game_count}")
- except AttributeError:
- print("Can't set game count. Maybe window hasn't loaded yet")
-
- def on_size(self, event):
- # Calculate the width of each column based on the width of the list control
- width = self.list_ctrl.GetSize()[0]
- col_width = width // 2
- self.list_ctrl.SetColumnWidth(0, col_width)
- self.list_ctrl.SetColumnWidth(1, col_width)
- event.Skip()
-
- def on_submit(self, event):
- name = self.name_field.GetValue()
- if not name:
- print("You didn't enter anything!")
- else:
- # Check if the player has already joined the lobby
- player_exists = False
- for player in self.last_lobby_state:
- if player['player_id'] == self.app.player_id:
- player_exists = True
- break
- if player_exists:
- # If the player already exists, rename them
- self.app.parse_response(send(f"lobby rename {self.app.player_id} {name}"))
- else:
- # If the player doesn't exist, join the lobby
- self.app.parse_response(send(f"lobby join {name}"))
- self.name_field.SetValue("")
-
- def on_text_enter(self, event):
- self.on_submit(event)
-
- def api_call(self, message):
- if connection_check():
- self.app.parse_response(send(message))
- self.name_field.SetValue("")
-
- def get_lobby_status(self, event=None):
- if not self.app.in_game and connection_check():
- self.app.parse_response(send(f"lobby get_status {self.app.player_id}"))
- if self.app.lobby == self.last_lobby_state:
- # If the current lobby state is the same as the last one, don't update the list control
- self.set_game_count()
- return
- self.list_ctrl.DeleteAllItems()
- for index, player in enumerate(self.app.lobby):
- self.list_ctrl.InsertItem(index, player['name'])
- self.list_ctrl.SetItem(index, 1, "Ready" if player['is_ready'] else "Not Ready")
- if player['player_id'] == self.app.player_id:
- self.current_player_index = index
- self.list_ctrl.SetItemState(index, wx.LIST_STATE_SELECTED, wx.LIST_STATE_SELECTED)
- else:
- self.list_ctrl.SetItemState(index, 0, wx.LIST_STATE_SELECTED)
- # Save the new lobby state
- self.last_lobby_state = self.app.lobby
- self.set_game_count()
-
- def highlight_current_player(self, event=None):
- if self.current_player_index is not None:
- self.list_ctrl.Select(self.current_player_index)
- else:
- self.list_ctrl.Select(-1)
-
- def on_ready_up(self, event):
- for player in self.app.lobby:
- if player['player_id'] == self.app.player_id:
- if player['is_ready']:
- if connection_check():
- self.app.parse_response(send(f"lobby unready {self.app.player_id}"))
- else:
- if connection_check():
- self.app.parse_response(send(f"lobby ready {self.app.player_id}"))
- break
-
- def enter_game(self, event=None):
- self.app.game_frame.Show()
- self.Hide()
-
- def on_close(self, event):
- try:
- self.app.parse_response(send(f"lobby leave {self.app.player_id}"))
- except ConnectionRefusedError:
- print("Server may be down. Exiting anyway.")
- self.Destroy()
-
-
-class DebugFrame(wx.Frame):
- def __init__(self, app):
- super().__init__(parent=None, title='VCKO Debug Console', size=Constants.small_window_size)
- self.app = app
- self.panel = wx.Panel(self)
- self.vertical_sizer = wx.BoxSizer(wx.VERTICAL)
- self.status_sizer = wx.BoxSizer(wx.HORIZONTAL)
- self.message_field = wx.TextCtrl(self.panel, style=wx.TE_PROCESS_ENTER)
- self.connection_status_indicator = wx.StaticText(self.panel, label="Connection Status")
- self.my_btn = wx.Button(self.panel, label="Send call")
- self.my_btn.Bind(wx.EVT_BUTTON, self.on_press)
- self.message_field.Bind(wx.EVT_TEXT_ENTER, self.on_text_enter)
- # Create a horizontal sizer to hold the connection_status StaticText
- self.status_sizer.AddStretchSpacer()
- self.status_sizer.Add(wx.StaticText(self.panel), 0, wx.EXPAND | wx.RIGHT, 5)
- self.status_sizer.Add(self.connection_status_indicator, 0, wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, 5)
- self.status_sizer.Add(wx.StaticText(self.panel), 0, wx.EXPAND | wx.LEFT, 5)
- # Add the text field, button, and status sizer to the vertical sizer
- self.vertical_sizer.Add(self.message_field, 0, wx.ALL | wx.EXPAND, 5)
- self.vertical_sizer.Add(self.my_btn, 0, wx.ALL | wx.CENTER, 5)
- self.vertical_sizer.AddStretchSpacer()
- self.vertical_sizer.Add(self.status_sizer, 0, wx.ALIGN_LEFT | wx.BOTTOM, 5)
- self.panel.SetSizer(self.vertical_sizer)
- self.SetMinSize(Constants.small_window_size)
- self.timer = wx.Timer(self)
- self.Bind(wx.EVT_TIMER, self.set_connection_status, self.timer)
- self.timer.Start(10000)
- self.set_connection_status()
-
- def set_connection_status(self, event=None):
- if connection_check():
- self.connection_status_indicator.SetLabel("Connected")
- self.connection_status_indicator.SetForegroundColour(Constants.green)
- else:
- self.connection_status_indicator.SetLabel("Not Connected")
- self.connection_status_indicator.SetForegroundColour(Constants.red)
-
- def on_press(self, event):
- message = self.message_field.GetValue()
- if not message:
- print("You didn't enter anything!")
- else:
- self.api_call(message)
-
- def on_text_enter(self, event):
- self.on_press(event)
-
- def api_call(self, message):
- if connection_check():
- self.app.parse_response(send(message))
- self.message_field.SetValue("")
-
-
-def connection_check():
- try:
- response = send("connection_check")
- if response == "received":
- return True
- else:
- return False
- except ConnectionRefusedError:
- return False
- except BrokenPipeError:
- return False
-
-
-def send(message):
- client_socket = socket.socket()
- client_socket.connect((Constants.host, Constants.port))
- message_bytes = message.encode(Constants.encoding)
- send_data(client_socket, message_bytes)
- response = receive_data(client_socket)
- client_socket.close()
- return response.decode(Constants.encoding)
-
-
-if __name__ == '__main__':
- the_app = ClientVCKO()
- the_app.MainLoop()
diff --git a/domains.py b/domains.py
deleted file mode 100644
index e69de29..0000000
diff --git a/dukes.py b/dukes.py
deleted file mode 100644
index e69de29..0000000
diff --git a/image.jpg b/image.jpg
deleted file mode 100644
index 0a6bd3f..0000000
Binary files a/image.jpg and /dev/null differ
diff --git a/server.py b/server.py
deleted file mode 100755
index 9596490..0000000
--- a/server.py
+++ /dev/null
@@ -1,362 +0,0 @@
-import socket
-import time
-import threading
-from common import *
-import json
-import mariadb
-
-
-class ServerVCKO:
- def __init__(self):
- self.host = socket.gethostbyname(socket.gethostname())
- self.server_socket = socket.socket()
- self.server_socket.bind((self.host, Constants.port))
- self.game_dict = {}
- self.lobby = []
- self.gamers = []
-
- # Start the thread to remove inactive players
- self.inactive_player_thread = threading.Thread(target=self.remove_inactive, daemon=True)
- self.inactive_player_thread.start()
-
- def remove_inactive(self):
- while True:
- current_time = time.time()
- self.lobby = [player for player in self.lobby if current_time - player.last_active_time <= 60]
- inactive_games = [game_id for game_id, game in self.game_dict.items() if
- current_time - game.last_active_time > 180]
- for game_id in inactive_games:
- del self.game_dict[game_id]
- time.sleep(10)
-
- def handle_client(self, conn, addr):
- print(f"Connection from: {addr}")
- connected = True
- while connected:
- msg_length = conn.recv(Constants.header_size).decode(Constants.text_format)
- if msg_length:
- msg_length = int(msg_length)
- msg = conn.recv(msg_length).decode(Constants.text_format)
- first_word = msg.split()[0]
- full_command = msg.split()
- match first_word:
- case "connection_check":
- connected = False
- send_data(conn, "received".encode(Constants.encoding))
- case "lobby":
- connected = False
- if full_command[1] == "join" and len(full_command) > 2:
- joining_player_name = ' '.join(full_command[2:])
- joining_player_id = str(shortuuid.uuid())
- joining_player = LobbyMember(joining_player_name, joining_player_id)
- self.lobby.append(joining_player)
- message = f"lobby joined {joining_player_id}"
- send_data(conn, message.encode(Constants.encoding))
- elif full_command[1] == "rename" and len(full_command) > 3:
- for player in self.lobby:
- if player.player_id == full_command[2]:
- player.name = ' '.join(full_command[3:])
- message = f"lobby renamed {player.player_id}"
- send_data(conn, message.encode(Constants.encoding))
- else:
- send_data(conn, "invalid message".encode(Constants.encoding))
- elif full_command[1] == "leave" and len(full_command) > 2:
- temp_lobby = []
- for player in self.lobby:
- if player.player_id != full_command[2]:
- temp_lobby.append(player)
- self.lobby = temp_lobby
- self.send_lobby_state(conn)
- elif full_command[1] == "get_status" and len(full_command) >= 2:
- found = False
- if len(full_command) == 3:
- for player in self.lobby:
- if full_command[2] == player.player_id:
- player.last_active_time = time.time() # update last active time
- self.send_lobby_state(conn)
- for player in self.gamers:
- if full_command[2] == player.player_id:
- message = f"game joined {player.game_id}"
- send_data(conn, message.encode(Constants.encoding))
- else:
- self.send_lobby_state(conn)
- elif full_command[1] == "ready" and len(full_command) > 2:
- ready_check = 0
- for player in self.lobby:
- if player.player_id == full_command[2]:
- player.is_ready = True
- if player.is_ready:
- ready_check += 1
- print(f"ready check: {ready_check}")
- if ready_check == len(self.lobby):
- new_game_id = str(uuid.uuid4())
- for player in self.lobby:
- print(f"lobby player: {player.name}")
- players_to_remove = []
- for player in self.lobby:
- if player.is_ready:
- new_gamer = GameMember(player.player_id, player.name, new_game_id)
- self.gamers.append(new_gamer)
- players_to_remove.append(player)
- for player in players_to_remove:
- self.lobby.remove(player)
- # START GAME
- new_game = Game(load_game_data(new_game_id, "base1", self.gamers))
- self.game_dict[new_game.game_id] = new_game
- print(f"size of game dict: {len(self.game_dict)}")
- message = f"game joined {new_game_id}"
- send_data(conn, message.encode(Constants.encoding))
- else:
- self.send_lobby_state(conn)
- elif full_command[1] == "unready" and len(full_command) > 2:
- for player in self.lobby:
- if player.player_id == full_command[2]:
- player.is_ready = False
- self.send_lobby_state(conn)
- else:
- send_data(conn, "invalid message".encode(Constants.encoding))
- case "game":
- connected = False
- if full_command[1] == "get_status" and len(full_command) == 3:
- print(full_command[2])
- print(len(self.game_dict))
- for game in self.game_dict:
- print(f"game id: {game}")
- game_id = full_command[2]
- game = self.game_dict.get(game_id)
- if not game:
- message = "game state error: game not found"
- send_data(conn, message.encode(Constants.encoding))
- else:
- game.last_active_time = time.time()
- self.send_game_state(conn, full_command[2])
- case _:
- connected = False
- send_data(conn, "invalid message".encode(Constants.encoding))
- print(f"[{addr}] {msg}")
- conn.close()
-
- def start(self):
- self.server_socket.listen()
- print(f"server is listening on {socket.gethostbyname(socket.gethostname())}")
- while True:
- conn, addr = self.server_socket.accept()
- thread = threading.Thread(target=self.handle_client, args=(conn, addr))
- thread.start()
- print(f"\nActive threads: {threading.active_count() - 1}")
-
- def send_lobby_state(self, conn):
- lobby_data = []
- for lobby_member in self.lobby:
- player_dict = {
- "name": lobby_member.name,
- "player_id": lobby_member.player_id,
- "is_ready": lobby_member.is_ready
- }
- lobby_data.append(player_dict)
- lobby_data.append({'game_count': len(self.game_dict)})
- response = f"lobby state {json.dumps(lobby_data)}"
- print(response)
- send_data(conn, response.encode(Constants.encoding))
-
- def send_game_state(self, conn, game_id):
- game = self.game_dict.get(game_id)
- if not game:
- response = "game state error: game not found"
- else:
- game_json = json.dumps(game, cls=GameObjectEncoder, indent=2)
- response = f"game state {game_json}"
- send_data(conn, response.encode(Constants.encoding))
-
-
-def load_game_data(game_id, preset, player_list_from_lobby):
- monster_query = ""
- monster_stack = []
- citizen_query = ""
- citizen_stack = []
- domain_query = "select_random_domains"
- domain_stack = []
- duke_query = "select_random_dukes"
- duke_stack = []
- starter_query = "SELECT * FROM starters"
- starter_stack = []
- player_list = []
- citizen_grid: List[List[Citizen]] = [[] for _ in range(10)]
- domain_grid: List[List[Domain]] = [[] for _ in range(5)]
- monster_grid: List[List[Monster]] = [[] for _ in range(5)]
- die_one = 0
- die_two = 0
- die_sum = 0
- exhausted_count = 0
- effects = {
- "roll_phase": [],
- "harvest_phase": [],
- "action_phase": []
- }
- action_required = {
- "player_id": "",
- "action": ""
- }
- match preset:
- case "base1":
- monster_query = "select_base1_monsters"
- citizen_query = "select_base1_citizens"
- case "base2":
- monster_query = "select_base2_monsters"
- citizen_query = "select_base2_citizens"
- try:
- my_connect = mariadb.connect(user='vckonline', password='vckonline', host='127.0.0.1',
- database='vckonline')
- my_cursor = my_connect.cursor(dictionary=True)
-
- my_cursor.callproc(monster_query)
-
- results = my_cursor.fetchall()
- for row in results:
- my_monster = Monster(row['id_monsters'], row['name'], row['area'], row['monster_type'],
- row['monster_order'], row['strength_cost'], row['magic_cost'], row['vp_reward'],
- row['gold_reward'], row['strength_reward'], row['magic_reward'],
- row['has_special_reward'], row['special_reward'], row['has_special_cost'],
- row['special_cost'], row['is_extra'], row['expansion'])
- monster_stack.append(my_monster)
-
- my_cursor.callproc(citizen_query)
- citizen_count = 5
- if len(player_list_from_lobby) == 5:
- citizen_count = 6
- results = my_cursor.fetchall()
- for row in results:
- for i in range(citizen_count):
- my_citizen = Citizen(row['id_citizens'], row['name'], row['gold_cost'], row['roll_match1'],
- row['roll_match2'], row['shadow_count'], row['holy_count'], row['soldier_count'],
- row['worker_count'], row['gold_payout_on_turn'], row['gold_payout_off_turn'],
- row['strength_payout_on_turn'], row['strength_payout_off_turn'],
- row['magic_payout_on_turn'], row['magic_payout_off_turn'],
- row['has_special_payout_on_turn'], row['has_special_payout_off_turn'],
- row['special_payout_on_turn'], row['special_payout_off_turn'],
- row['special_citizen'],
- row['expansion'])
- citizen_stack.append(my_citizen)
-
- my_cursor.callproc(domain_query)
- results = my_cursor.fetchall()
- for row in results:
- my_domain = Domain(row['id_domains'], row['name'], row['gold_cost'], row['shadow_count'], row['holy_count'],
- row['soldier_count'], row['worker_count'], row['vp_reward'],
- row['has_activation_effect'], row['has_passive_effect'], row['passive_effect'],
- row['activation_effect'], row['text'], row['expansion'])
- domain_stack.append(my_domain)
-
- my_cursor.callproc(duke_query)
- results = my_cursor.fetchall()
- for row in results:
- my_duke = Duke(row['id_dukes'], row['name'], row['gold_mult'], row['strength_mult'], row['magic_mult'],
- row['shadow_mult'], row['holy_mult'], row['soldier_mult'], row['worker_mult'],
- row['monster_mult'], row['citizen_mult'], row['domain_mult'], row['boss_mult'],
- row['minion_mult'], row['beast_mult'], row['titan_mult'], row['expansion'])
- duke_stack.append(my_duke)
-
- my_cursor.execute(starter_query)
- my_result = my_cursor.fetchall()
- for row in my_result:
- my_starter = Starter(row['id_starters'], row['name'], row['roll_match1'], row['roll_match2'],
- row['gold_payout_on_turn'], row['gold_payout_off_turn'],
- row['strength_payout_on_turn'], row['strength_payout_off_turn'],
- row['magic_payout_on_turn'], row['magic_payout_off_turn'],
- row['has_special_payout_on_turn'], row['has_special_payout_off_turn'],
- row['special_payout_on_turn'], row['special_payout_off_turn'], row['expansion'])
- starter_stack.append(my_starter)
- my_cursor.close()
- my_connect.close()
- except Exception as e:
- print(f"Error: {e}")
- # print(f"size of monster stack: {len(monster_stack)}")
- # print(f"size of citizen stack: {len(citizen_stack)}")
- # print(f"size of domain stack: {len(domain_stack)}")
- # print(f"size of duke stack: {len(duke_stack)}")
- # print(f"size of starter stack: {len(starter_stack)}")
- # create players and determine order
- if not all([player_list_from_lobby, starter_query, monster_stack, citizen_stack, domain_stack, duke_stack]):
- raise ValueError("One or more required lists are empty.")
- else:
- for player in player_list_from_lobby:
- my_player = Player(player.player_id, player.name)
- player_list.append(my_player)
- random.shuffle(player_list)
- player_list[0].is_first = True
- # give players starters and dukes
- for player in player_list:
- player.owned_starters.append(starter_stack[0])
- player.owned_starters.append(starter_stack[1])
- for i in range(2):
- player.owned_dukes.append(duke_stack.pop())
- # deal monsters onto the board
- grouped_monsters = {}
- for monster in monster_stack:
- area = monster.area
- if area in grouped_monsters:
- grouped_monsters[area].append(monster)
- else:
- grouped_monsters[area] = [monster]
- # Reverse the order of each group by monster_order
- for area, monsters in grouped_monsters.items():
- monsters.sort(key=lambda item: item.order, reverse=True)
- areas = list(grouped_monsters.keys())
- chosen_areas = random.sample(areas, 5)
- for i, area in enumerate(chosen_areas):
- monsters = grouped_monsters[area]
- monster_grid[i].extend(monsters)
- for i, stack in enumerate(monster_grid):
- for monster in stack:
- monster.toggle_visibility(True)
- # Make the last monster in the stack accessible
- stack[-1].toggle_accessibility(True)
- monster_stack = []
- # deal citizens onto the board
- # Create a dictionary to store citizen lists with roll numbers as keys
- citizens_by_roll = {roll: [] for roll in [1, 2, 3, 4, 5, 6, 7, 8, 9, 11]}
- # Group citizens by roll number
- for citizen in citizen_stack:
- citizen.toggle_visibility()
- citizens_by_roll[citizen.roll_match1].append(citizen)
- for roll in citizens_by_roll:
- # Map 11 roll to index 9
- index = roll - 1 if roll < 11 else 9
- citizens = citizens_by_roll[roll]
- citizen_grid[index].extend(list(citizens))
- # Make the first citizen in each list accessible
- citizen_grid[index][-1].toggle_accessibility(True)
- citizen_stack = []
- # Deal the domains into the stacks
- for i in range(5):
- stack = domain_grid[i]
- for j in range(3):
- if j == 2: # top domain is visible and accessible
- domain = domain_stack.pop()
- domain.toggle_visibility(True)
- domain.toggle_accessibility(True)
- stack.append(domain)
- else: # other domains are not visible or accessible
- domain = domain_stack.pop()
- stack.append(domain)
-
- # Create a dictionary to store all the stacks
- game_state = {'game_id': game_id,
- 'player_list': player_list,
- 'monster_grid': monster_grid,
- 'citizen_grid': citizen_grid,
- 'domain_grid': domain_grid,
- 'die_one': die_one,
- 'die_two': die_two,
- 'die_sum': die_sum,
- 'exhausted_count': exhausted_count,
- 'effects': effects,
- 'action_required': action_required}
- # Return the dictionary
- return game_state
-
-
-if __name__ == '__main__':
- print("server starting")
- server = ServerVCKO()
- server.start()
diff --git a/vckoclient.html b/vckoclient.html
deleted file mode 100644
index 0b9e0e2..0000000
--- a/vckoclient.html
+++ /dev/null
@@ -1,49 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
- WebSocker Client
-
-
-
-
-
-
-
-
-
-
-
-