Skip to content

Commit

Permalink
add client, game server, and basic authentication server (#19)
Browse files Browse the repository at this point in the history
* add command line argument to choose to run as server vs. client

* rename game_simulation.jl to simulate.jl

* arrange imports in alphabetical order

* add Sockets module to project files

* allow only 3 clients for now

* identify what (server/client) is running and where (host and port)

* create function start_server_and_fill_room

remove CLIENT_HOSTS, CLIENT_PORTS since they are not in our control
becaue Sockets.connect method will automatically give us the bound
TCPSocket

* add function start_client, remove THIS_CLIENT_ID as it doens't matter
when running the script (it is the server that must identify the client
and not the script/client itself)

* rename socket_peer_name to peername

* rename start_server_and_fill_room to start_server, return nothing for
start_server and start_client

* add HTTP package to project files

* use enum Actor instead of Bool IS_SERVER

* rename server to game_server

* use InetAddr instead of host and port separately

* remove Actor and just do stuff in the if else

* add basic auth server

* add Base64 to project files

* add credential validation

* pass username and password arguments to start_client function
  • Loading branch information
Sid-Bhatia-0 authored Feb 18, 2024
1 parent f3b562b commit 882ed89
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 3 deletions.
84 changes: 83 additions & 1 deletion netcode/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

julia_version = "1.9.3"
manifest_format = "2.0"
project_hash = "7ca2997eb61b6ee53c6258e185fe45377e4133a0"
project_hash = "c315683188dfdbd5d0f9952249606f482e2ab3b2"

[[deps.ArgTools]]
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
Expand All @@ -14,6 +14,17 @@ uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
[[deps.Base64]]
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"

[[deps.BitFlags]]
git-tree-sha1 = "2dc09997850d68179b69dafb58ae806167a32b1b"
uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35"
version = "0.1.8"

[[deps.CodecZlib]]
deps = ["TranscodingStreams", "Zlib_jll"]
git-tree-sha1 = "59939d8a997469ee05c4b4944560a820f9ba0d73"
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
version = "0.7.4"

[[deps.Compat]]
deps = ["TOML", "UUIDs"]
git-tree-sha1 = "75bd5b6fc5089df449b5d35fa501c846c9b6549b"
Expand All @@ -29,6 +40,12 @@ deps = ["Artifacts", "Libdl"]
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
version = "1.0.5+0"

[[deps.ConcurrentUtilities]]
deps = ["Serialization", "Sockets"]
git-tree-sha1 = "9c4708e3ed2b799e6124b5673a712dda0b596a9b"
uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb"
version = "2.3.1"

[[deps.Crayons]]
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
Expand Down Expand Up @@ -65,13 +82,25 @@ deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"]
uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6"
version = "1.6.0"

[[deps.ExceptionUnwrapping]]
deps = ["Test"]
git-tree-sha1 = "dcb08a0d93ec0b1cdc4af184b26b591e9695423a"
uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4"
version = "0.1.10"

[[deps.FileWatching]]
uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee"

[[deps.Future]]
deps = ["Random"]
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"

[[deps.HTTP]]
deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"]
git-tree-sha1 = "abbbb9ec3afd783a7cbd82ef01dcd088ea051398"
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
version = "1.10.1"

[[deps.InlineStrings]]
deps = ["Parsers"]
git-tree-sha1 = "9cc2baf75c6d09f9da536ddf58eb2f29dedaf461"
Expand All @@ -92,6 +121,12 @@ git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
uuid = "82899510-4779-5014-852e-03e436cf321d"
version = "1.0.0"

[[deps.JLLWrappers]]
deps = ["Artifacts", "Preferences"]
git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca"
uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210"
version = "1.5.0"

[[deps.LaTeXStrings]]
git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec"
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
Expand Down Expand Up @@ -126,10 +161,22 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
[[deps.Logging]]
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"

[[deps.LoggingExtras]]
deps = ["Dates", "Logging"]
git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075"
uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36"
version = "1.0.3"

[[deps.Markdown]]
deps = ["Base64"]
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"

[[deps.MbedTLS]]
deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"]
git-tree-sha1 = "c067a280ddc25f196b5e7df3877c6b226d390aaf"
uuid = "739be429-bea8-5141-9913-cc70e7f3736d"
version = "1.1.9"

[[deps.MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
Expand All @@ -154,6 +201,18 @@ deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
version = "0.3.21+4"

[[deps.OpenSSL]]
deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "OpenSSL_jll", "Sockets"]
git-tree-sha1 = "51901a49222b09e3743c65b8847687ae5fc78eb2"
uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c"
version = "1.4.1"

[[deps.OpenSSL_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
git-tree-sha1 = "60e3045590bd104a16fefb12836c00c0ef8c7f8c"
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
version = "3.0.13+0"

[[deps.OrderedCollections]]
git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5"
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
Expand Down Expand Up @@ -224,6 +283,11 @@ version = "1.4.1"
[[deps.Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"

[[deps.SimpleBufferStream]]
git-tree-sha1 = "874e8867b33a00e784c8a7e4b60afe9e037b74e1"
uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7"
version = "1.1.0"

[[deps.Sockets]]
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"

Expand Down Expand Up @@ -275,6 +339,24 @@ deps = ["ArgTools", "SHA"]
uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e"
version = "1.10.0"

[[deps.Test]]
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[[deps.TranscodingStreams]]
git-tree-sha1 = "54194d92959d8ebaa8e26227dbe3cdefcdcd594f"
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
version = "0.10.3"
weakdeps = ["Random", "Test"]

[deps.TranscodingStreams.extensions]
TestExt = ["Test", "Random"]

[[deps.URIs]]
git-tree-sha1 = "67db6cc7b3821e19ebe75791a9dd19c9b1188f2b"
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
version = "1.5.1"

[[deps.UUIDs]]
deps = ["Random", "SHA"]
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
Expand Down
3 changes: 3 additions & 0 deletions netcode/Project.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
111 changes: 109 additions & 2 deletions netcode/game_simulation.jl → netcode/simulate.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,29 @@
import Statistics
import Base64
import DataFrames as DF
import HTTP
import Sockets
import Statistics

const ROOM_SIZE = 3

const GAME_SERVER_ADDR = Sockets.InetAddr(Sockets.localhost, 10000)

const AUTH_SERVER_ADDR = Sockets.InetAddr(Sockets.localhost, 10001)

const NULL_TCP_SOCKET = Sockets.TCPSocket()

const VALID_CREDENTIALS = Set(Base64.base64encode("user$(i):password$(i)") for i in 1:3)

const CLIENT_USERNAME = "user1"

const CLIENT_PASSWORD = "password1"

struct ClientSlot
is_used::Bool
socket::Sockets.TCPSocket
end

const NULL_CLIENT_SLOT = ClientSlot(false, NULL_TCP_SOCKET)

struct DebugInfo
frame_end_time_buffer::Vector{Int}
Expand Down Expand Up @@ -65,6 +89,68 @@ function create_df_debug_info(debug_info)
)
end

function start_game_server(game_server_addr, room_size)
room = fill(NULL_CLIENT_SLOT, 3)

game_server = Sockets.listen(game_server_addr)
@info "Server started listening"

for i in 1:ROOM_SIZE
client_slot = ClientSlot(true, Sockets.accept(game_server))
room[i] = client_slot

client_addr = Sockets.InetAddr(Sockets.getpeername(client_slot.socket)...)

@info "Socket accepted" client_addr
end

@info "Room full" game_server room

return nothing
end

function start_client(auth_server_addr, username, password)
response = HTTP.get("http://" * username * ":" * password * "@" * string(auth_server_addr.host) * ":" * string(auth_server_addr.port))

game_server_host_string, game_server_port_string = split(String(response.body), ":")

game_server_addr = Sockets.InetAddr(game_server_host_string, parse(Int, game_server_port_string))

@info "Client obtained game_server_addr" game_server_addr

socket = Sockets.connect(game_server_addr)

client_addr = Sockets.InetAddr(Sockets.getsockname(socket)...)

@info "Client connected to game_server" client_addr

return nothing
end

function auth_handler(request)
try
i = findfirst(x -> x.first == "Authorization", request.headers)

if isnothing(i)
return HTTP.Response(400, "ERROR: Authorization not found in header")
else
if startswith(request.headers[i].second, "Basic ")
if split(request.headers[i].second)[2] in VALID_CREDENTIALS
return HTTP.Response(200, string(GAME_SERVER_ADDR.host) * ":" * string(GAME_SERVER_ADDR.port))
else
return HTTP.Response(400, "ERROR: Invalid credentials")
end
else
return HTTP.Response(400, "ERROR: Authorization type must be Basic authorization")
end
end
catch e
return HTTP.Response(400, "ERROR: $e")
end
end

start_auth_server(auth_server_addr) = HTTP.serve(auth_handler, auth_server_addr.host, auth_server_addr.port)

function start()
target_frame_rate = 60
total_frames = target_frame_rate * 2
Expand Down Expand Up @@ -97,4 +183,25 @@ function start()
return nothing
end

start()
@assert length(ARGS) == 1

if ARGS[1] == "--game_server"
@info "Running as game_server" GAME_SERVER_ADDR AUTH_SERVER_ADDR

start_game_server(GAME_SERVER_ADDR, ROOM_SIZE)

elseif ARGS[1] == "--auth_server"
@info "Running as auth_server" GAME_SERVER_ADDR AUTH_SERVER_ADDR

start_auth_server(AUTH_SERVER_ADDR)

elseif ARGS[1] == "--client"
@info "Running as client" GAME_SERVER_ADDR AUTH_SERVER_ADDR

start_client(AUTH_SERVER_ADDR, CLIENT_USERNAME, CLIENT_PASSWORD)

else
error("Invalid command line argument $(ARGS[1])")
end

# start()

0 comments on commit 882ed89

Please sign in to comment.