| from fastapi import FastAPI, WebSocket, WebSocketDisconnect |
| import uvicorn |
| import json |
| import os |
| import uuid |
|
|
| app = FastAPI() |
|
|
| PLAYERS_FILE = "players.json" |
| ENTREPRISES_FILE = "entreprises.json" |
|
|
| clients = {} |
| logged_users = {} |
| player_positions = {} |
| coop_requests = {} |
|
|
| |
| |
| |
|
|
| def load_players(): |
|
|
| if os.path.exists(PLAYERS_FILE): |
|
|
| with open( |
| PLAYERS_FILE, |
| "r", |
| encoding="utf-8" |
| ) as f: |
|
|
| return json.load(f) |
|
|
| return {} |
|
|
| def save_players(): |
|
|
| with open( |
| PLAYERS_FILE, |
| "w", |
| encoding="utf-8" |
| ) as f: |
|
|
| json.dump( |
| players_data, |
| f, |
| indent=4, |
| ensure_ascii=False |
| ) |
|
|
| |
| |
| |
|
|
| def load_entreprises(): |
|
|
| if os.path.exists( |
| ENTREPRISES_FILE |
| ): |
|
|
| with open( |
| ENTREPRISES_FILE, |
| "r", |
| encoding="utf-8" |
| ) as f: |
|
|
| return json.load(f) |
|
|
| return {} |
|
|
| def save_entreprises(): |
|
|
| with open( |
| ENTREPRISES_FILE, |
| "w", |
| encoding="utf-8" |
| ) as f: |
|
|
| json.dump( |
| entreprises_data, |
| f, |
| indent=4, |
| ensure_ascii=False |
| ) |
|
|
| players_data = load_players() |
| entreprises_data = load_entreprises() |
|
|
| |
| |
| |
|
|
| @app.websocket("/ws") |
| async def websocket_endpoint( |
| ws: WebSocket |
| ): |
|
|
| await ws.accept() |
|
|
| session_id = str( |
| uuid.uuid4() |
| ) |
|
|
| clients[session_id] = ws |
|
|
| username = None |
|
|
| await ws.send_text(json.dumps({ |
| "type":"welcome", |
| "id":session_id |
| })) |
|
|
| try: |
|
|
| while True: |
|
|
| text = await ws.receive_text() |
|
|
| data = json.loads(text) |
|
|
| msg_type = data.get( |
| "type", |
| "" |
| ) |
|
|
| |
| |
| |
|
|
| if msg_type == "login": |
|
|
| user = str( |
| data.get( |
| "username", |
| "" |
| ) |
| ).strip() |
|
|
| password = str( |
| data.get( |
| "password", |
| "" |
| ) |
| ).strip() |
|
|
| if ( |
| user == "" |
| or |
| password == "" |
| ): |
|
|
| await ws.send_text( |
| json.dumps({ |
| "type":"login_failed" |
| }) |
| ) |
|
|
| continue |
|
|
| if user not in players_data: |
|
|
| players_data[user] = { |
| "password":password, |
| "money":0, |
| "progress":1 |
| } |
|
|
| save_players() |
|
|
| elif ( |
| players_data[user]["password"] |
| != password |
| ): |
|
|
| await ws.send_text( |
| json.dumps({ |
| "type":"login_failed" |
| }) |
| ) |
|
|
| continue |
|
|
| username = user |
|
|
| logged_users[ |
| session_id |
| ] = username |
|
|
| await ws.send_text( |
| json.dumps({ |
| "type":"login_success" |
| }) |
| ) |
|
|
| await ws.send_text( |
| json.dumps({ |
| "type":"player_data", |
| "money": |
| players_data[user]["money"], |
| "progress": |
| players_data[user]["progress"] |
| }) |
| ) |
|
|
| for sid in clients.keys(): |
|
|
| if sid == session_id: |
| continue |
|
|
| await ws.send_text( |
| json.dumps({ |
| "type":"player_join", |
| "id":sid |
| }) |
| ) |
|
|
| for sid, client in clients.items(): |
|
|
| if sid == session_id: |
| continue |
|
|
| try: |
|
|
| await client.send_text( |
| json.dumps({ |
| "type":"player_join", |
| "id":session_id |
| }) |
| ) |
|
|
| except: |
| pass |
|
|
| for path, owner in ( |
| entreprises_data.items() |
| ): |
|
|
| await ws.send_text( |
| json.dumps({ |
| "type":"entreprise_owner", |
| "path":path, |
| "owner":owner |
| }) |
| ) |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "player_update" |
| ): |
|
|
| player_positions[ |
| session_id |
| ] = { |
|
|
| "x": |
| data.get("x",0), |
|
|
| "y": |
| data.get("y",0), |
|
|
| "z": |
| data.get("z",0) |
| } |
|
|
| data["id"] = session_id |
|
|
| for sid, client in clients.items(): |
|
|
| if sid == session_id: |
| continue |
|
|
| try: |
|
|
| await client.send_text( |
| json.dumps( |
| data |
| ) |
| ) |
|
|
| except: |
| pass |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "save_money" |
| ): |
|
|
| if username: |
|
|
| players_data[ |
| username |
| ]["money"] = int( |
| data.get( |
| "money", |
| 0 |
| ) |
| ) |
|
|
| save_players() |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "save_progress" |
| ): |
|
|
| if username: |
|
|
| progress = int( |
| data.get( |
| "progress", |
| 1 |
| ) |
| ) |
|
|
| players_data[ |
| username |
| ]["progress"] = progress |
|
|
| save_players() |
|
|
| broadcast = { |
| "type":"player_progress", |
| "id":session_id, |
| "progress":progress |
| } |
|
|
| for sid, client in clients.items(): |
|
|
| if sid == session_id: |
| continue |
|
|
| try: |
|
|
| await client.send_text( |
| json.dumps( |
| broadcast |
| ) |
| ) |
|
|
| except: |
| pass |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "save_entreprise" |
| ): |
|
|
| path = data.get( |
| "path", |
| "" |
| ) |
|
|
| owner = data.get( |
| "owner", |
| "" |
| ) |
|
|
| entreprises_data[ |
| path |
| ] = owner |
|
|
| save_entreprises() |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "set_entreprise_owner" |
| ): |
|
|
| path = data.get( |
| "path", |
| "" |
| ) |
|
|
| owner = data.get( |
| "owner", |
| "" |
| ) |
|
|
| entreprises_data[ |
| path |
| ] = owner |
|
|
| save_entreprises() |
|
|
| broadcast = { |
| "type":"entreprise_owner", |
| "path":path, |
| "owner":owner |
| } |
|
|
| for client in clients.values(): |
|
|
| try: |
|
|
| await client.send_text( |
| json.dumps( |
| broadcast |
| ) |
| ) |
|
|
| except: |
| pass |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "coop_invite" |
| ): |
|
|
| if username: |
|
|
| target = str( |
| data.get( |
| "target", |
| "" |
| ) |
| ).strip() |
|
|
| target_sid = None |
|
|
| for sid, uname in logged_users.items(): |
|
|
| if uname == target: |
|
|
| target_sid = sid |
|
|
| break |
|
|
| if ( |
| target_sid |
| and |
| target_sid in clients |
| ): |
|
|
| coop_requests[ |
| target_sid |
| ] = session_id |
|
|
| try: |
|
|
| await clients[ |
| target_sid |
| ].send_text( |
| json.dumps({ |
| "type":"coop_invite", |
| "sender":username |
| }) |
| ) |
|
|
| except: |
| pass |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "coop_accept" |
| ): |
|
|
| if username: |
|
|
| sender_name = str( |
| data.get( |
| "sender", |
| "" |
| ) |
| ).strip() |
|
|
| sender_sid = None |
|
|
| for sid, uname in logged_users.items(): |
|
|
| if uname == sender_name: |
|
|
| sender_sid = sid |
|
|
| break |
|
|
| if ( |
| sender_sid |
| and |
| sender_sid in clients |
| ): |
|
|
| if session_id in coop_requests: |
|
|
| del coop_requests[session_id] |
|
|
| try: |
|
|
| await clients[ |
| sender_sid |
| ].send_text( |
| json.dumps({ |
| "type":"coop_accept", |
| "from":username |
| }) |
| ) |
|
|
| except: |
| pass |
|
|
| |
| |
| |
|
|
| elif ( |
| msg_type |
| == |
| "coop_refuse" |
| ): |
|
|
| if username: |
|
|
| sender_name = str( |
| data.get( |
| "sender", |
| "" |
| ) |
| ).strip() |
|
|
| sender_sid = None |
|
|
| for sid, uname in logged_users.items(): |
|
|
| if uname == sender_name: |
|
|
| sender_sid = sid |
|
|
| break |
|
|
| if ( |
| sender_sid |
| and |
| sender_sid in clients |
| ): |
|
|
| if session_id in coop_requests: |
|
|
| del coop_requests[session_id] |
|
|
| try: |
|
|
| await clients[ |
| sender_sid |
| ].send_text( |
| json.dumps({ |
| "type":"coop_refuse", |
| "from":username |
| }) |
| ) |
|
|
| except: |
| pass |
|
|
| except WebSocketDisconnect: |
|
|
| pass |
|
|
| finally: |
|
|
| |
|
|
| if session_id in coop_requests: |
|
|
| del coop_requests[session_id] |
|
|
| for k, v in list( |
| coop_requests.items() |
| ): |
|
|
| if v == session_id: |
|
|
| del coop_requests[k] |
|
|
| |
|
|
| to_clear = [] |
|
|
| for path, owner in entreprises_data.items(): |
|
|
| if owner == session_id: |
|
|
| to_clear.append(path) |
|
|
| for path in to_clear: |
|
|
| entreprises_data[path] = "" |
|
|
| for client in clients.values(): |
|
|
| try: |
|
|
| await client.send_text( |
| json.dumps({ |
| "type":"entreprise_owner", |
| "path":path, |
| "owner":"" |
| }) |
| ) |
|
|
| except: |
| pass |
|
|
| save_entreprises() |
|
|
| if session_id in clients: |
| del clients[session_id] |
|
|
| if session_id in logged_users: |
| del logged_users[session_id] |
|
|
| if session_id in player_positions: |
| del player_positions[session_id] |
|
|
| for client in clients.values(): |
|
|
| try: |
|
|
| await client.send_text( |
| json.dumps({ |
| "type":"player_leave", |
| "id":session_id |
| }) |
| ) |
|
|
| except: |
| pass |
| if __name__ == "__main__": |
|
|
| port = int( |
| os.environ.get( |
| "PORT", |
| 7860 |
| ) |
| ) |
|
|
| uvicorn.run( |
| app, |
| host="0.0.0.0", |
| port=port |
| ) |