Server / app.py
lea97338's picture
Update app.py
dcba848 verified
Raw
History Blame Contribute Delete
15.7 kB
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 = {}
# ======================================================
# PLAYERS
# ======================================================
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
)
# ======================================================
# ENTREPRISES
# ======================================================
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()
# ======================================================
# WEBSOCKET
# ======================================================
@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",
""
)
# =====================================
# LOGIN
# =====================================
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
})
)
# =====================================
# POSITION
# =====================================
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
# =====================================
# MONEY
# =====================================
elif (
msg_type
==
"save_money"
):
if username:
players_data[
username
]["money"] = int(
data.get(
"money",
0
)
)
save_players()
# =====================================
# PROGRESS
# =====================================
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
# =====================================
# ENTREPRISE
# =====================================
elif (
msg_type
==
"save_entreprise"
):
path = data.get(
"path",
""
)
owner = data.get(
"owner",
""
)
entreprises_data[
path
] = owner
save_entreprises()
# =====================================
# CHANGE OWNER
# =====================================
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
# =====================================
# COOP INVITE
# =====================================
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
# =====================================
# COOP ACCEPT
# =====================================
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
# =====================================
# COOP REFUSE
# =====================================
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:
# Libération coop
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]
# Libération entreprises
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
)