About Social Code
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2025-03-31 21:47:45 +0100
committerLucas Fryzek <lucas.fryzek@fryzekconcepts.com>2025-03-31 21:47:45 +0100
commit01e0fa64363bb22c5e322ce2977637f483aea5c6 (patch)
tree2e8e280934c64760e75a4cb2409eb2242d60f4c6
parent3ba85e55e3bd5f28ce81aa1aa93f18a741f78ca2 (diff)
Add more packets and get json lib working with server data
-rw-r--r--main.rhm48
-rw-r--r--src/chunk.rhm18
-rw-r--r--src/world.rhm55
3 files changed, 94 insertions, 27 deletions
diff --git a/main.rhm b/main.rhm
index da4701d..bc41348 100644
--- a/main.rhm
+++ b/main.rhm
@@ -1,17 +1,11 @@
#lang rhombus/static
import:
- lib("web-server/http.rkt") open
- lib("web-server/servlet.rkt") open
- lib("web-server/servlet-env.rkt") open
+ lib("web-server/http.rkt") as http
+ lib("web-server/servlet-env.rkt") as servlet_env
"thread/thread.rhm" open
"src/world.rhm"
-
-fun start(req):
- println(#{request-method}(req))
- println(#{request-post-data/raw}(req))
- #{response/xexpr}("Hello world!")
-
+ "json/main.rhm" as json
fun loop():
println("Hello World!")
@@ -20,14 +14,48 @@ fun loop():
fun sim_world():
let wrld = world.World()
+ wrld.init()
wrld.simulate()
println("Creating thread")
def thr: thread(sim_world)
+fun start(req):
+ let type = http.#{request-method}(req)
+ let body = http.#{request-post-data/raw}(req)
+ cond
+ | type is_now #"POST":
+ let req_json :: Map = json.from_bytes(body)
+ cond
+ | req_json["cmd"] is_now "Login":
+ thread_send(thr, world.MessageLogin("test", current_thread()))
+ let response :: world.MessageLoginResponse = thread_receive()
+ http.#{response/full}(200, #"OK",
+ system.seconds(),
+ http.#{APPLICATION/JSON-MIME-TYPE},
+ PairList(),
+ PairList(json.to_bytes(response.to_map())))
+ | req_json["cmd"] is_now "GetChunk":
+ let user_id = math.exact(req_json["user_id"])
+ thread_send(thr, world.MessageGetChunks(user_id, current_thread()))
+ let response :: world.MessageGetChunksResponse = thread_receive()
+ http.#{response/full}(200, #"OK",
+ system.seconds(),
+ http.#{APPLICATION/JSON-MIME-TYPE},
+ PairList(),
+ PairList(json.to_bytes(response.to_map())))
+ | ~else:
+ http.#{response/full}(400, #"INVALID COMMAND",
+ system.seconds(),
+ http.#{APPLICATION/JSON-MIME-TYPE},
+ PairList(),
+ PairList())
+
+
+
// Create webserver
-#{serve/servlet}(start, #{#:launch-browser?}: #false, #{#:servlet-path}: "/game")
+servlet_env.#{serve/servlet}(start, #{#:launch-browser?}: #false, #{#:servlet-path}: "/game")
// Wait on world simulation thread so we don't kill the world before it has cleanly exited
thread_wait(thr)
diff --git a/src/chunk.rhm b/src/chunk.rhm
index 3ded42d..673d6e9 100644
--- a/src/chunk.rhm
+++ b/src/chunk.rhm
@@ -39,6 +39,14 @@ class Tile(type :: TileType):
| TileType.empty: #false
| TileType.wall_north: Direction.north
+ method to_tile_int():
+ match type
+ | TileType.empty: 0
+ | TileType.wall_north: 1
+
+ method to_map() :: Map:
+ {"type": to_tile_int()}
+
class Chunk(width :: Int,
height :: Int,
offset_x :: Int,
@@ -56,3 +64,13 @@ class Chunk(width :: Int,
method set_tile(x :: Int, y :: Int, tile :: Tile):
tiles[y * width + x] := tile
+
+ method to_map() :: Map:
+ {"width": width,
+ "height": height,
+ "offset_x": offset_x,
+ "offset_y": offset_y,
+ "tiles": for:
+ each tile :: Tile in tiles
+ tile.to_map()
+ ~into List}
diff --git a/src/world.rhm b/src/world.rhm
index 13fe048..01a1553 100644
--- a/src/world.rhm
+++ b/src/world.rhm
@@ -6,35 +6,55 @@ import:
"../thread/thread.rhm" open
export:
- Chunk
- ActionResponse
- Direction
- World
- Tile
- Entity
- EntityPlayer
- EntityGatherable
- Direction
- ItemCap
- Item
- Slot
+ all_defined
+
class MessageLogin(user :: String, thr)
+class MessageLoginResponse(user_id :: Int):
+ // TODO can I automate this?
+ method to_map() :: Map:
+ {"user_id": user_id}
+
+class MessageGetChunks(user_id :: Int, thr)
+
+class MessageGetChunksResponse(chunk :: Chunk):
+ method to_map() :: Map:
+ chunk.to_map()
+
class World(chunks :: MutableList.now_of(Chunk),
- entities :: MutableList.now_of(Entity)):
+ entities :: MutableMap.now_of(Int, Entity)):
field thread_evt = thread_receive_evt()
field tick_length = 0.6 // tick length is 600ms
+ // TODO this should really go to some user DB
+ field user_id = 100
+
constructor():
- super(MutableList(), MutableList())
+ super(MutableList(), MutableMap())
+
+ method init():
+ let chunk = Chunk(64, 64, 0, 0)
+ chunks.add(chunk)
method login(user :: String, thr):
- // TODO should be accessing some DB to get player
- let player = EntityPlayer(0, 0, 0, chunks)
+ // TODO should be accessing some DB to get player and it should
+ // return some session token that the client would use when refering
+ // to the player
+ let player = EntityPlayer(user_id, 0, 0, chunks[0])
player.equip[Slot.right_hand] := Item.bronze_axe
- entities.add(player)
+ entities[user_id] := player
+ let resp = MessageLoginResponse(user_id)
+ user_id := user_id + 1
+ thread_send(thr, resp)
+
+ method get_chunk(user_id :: Int, thr):
+ // TODO there should be a session token to user entity system
+ let player :: Entity = entities[user_id]
+ let chunk = player.current_chunk
+ let resp = MessageGetChunksResponse(chunk)
+ thread_send(thr, resp)
method process_messages(timestamp :: Real):
let time_passed = current_timestamp() - timestamp
@@ -44,6 +64,7 @@ class World(chunks :: MutableList.now_of(Chunk),
| let msg = thread_receive()
match msg
| MessageLogin(user, thr): login(user, thr)
+ | MessageGetChunks(user_id, thr): get_chunk(user_id, thr)
| ~else: println("Unknown message " +& msg)
process_messages(timestamp)
| #true // Return here