Skip to content

Commit

Permalink
The Big Client/ Server refactor (#195)
Browse files Browse the repository at this point in the history
* Start the server netcode re-write

* Begin work on new client for network stuff

* add connection state enum for network client

* Fix the cmakelists

* Write tests for network client class

* Add function to disconnect the client from the server

* Ensure packets are destroyed

* Add test for disconnecting from server

* Move the enet client connect/disconnect functions to be free functions
git push

* [ENet] Add broadcast method to enet helpers

* Create packet to hold data about packets

* Make the client/server classes use the new packet struct in the handle packet function

* Handle the handshake between the client and server

* move old network code into a temporary folder

* move more names into temp folder

* Create packet type for acceptig or rejecting a connection request

* Prevent disconneting clients with emptiness

* Write tests for if the server is full, reject the client

* Fix crash to do with the client not diconnecting orrectly

* Add extra test

* Created NetHost struct to be a wrapper around the basics of ENetHost

* [Server] Use the new enet host wrapper struct in the Server class

* [Client] Use new host struct in the client

* Update the packet class to be less error prone

* Move pending client session to new file

* [Server] Broadcast a player join event

* Add player leave events

* make server engine a non global variable

* Wrap client code into a nice class

* Create a state manager class to handle different game states

* allow gui events to be created via the c++ side

* Make the main menu switch to the in game tate

* vs what are you doing

* Revert back to more simple times

* Update game defintions to have specific game types, organising the code and creating a beter interface as a result

* Have the entity draw

* Move camera stuff to camera class

* Add fps controller

* Send player position over the network

* Handle players joining and leaving game correctly

* Add network event to update enttity positions

* Server sends voxel data to client

* send chunks from server to client

* Fix linux unit tests

* simplify the server code

* Make the selected box show around the voxel the player is currently looking at

* add packets for sending play spawn etc

* Hacky fix for the game now shutting down correctly

* Reimplement digging

* Reimplement block placing

* remove temp things

* Clang format and fix unit tests
  • Loading branch information
Hopson97 committed Apr 6, 2020
1 parent d67d365 commit 2861497
Show file tree
Hide file tree
Showing 73 changed files with 2,819 additions and 2,032 deletions.
12 changes: 10 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,13 @@ add_executable(${PROJECT_NAME}
src/main.cpp
)

target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/server/
)



target_include_directories(ob-common
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/deps/
Expand All @@ -111,13 +118,14 @@ add_executable(tests
tests/common/world/chunk_manager_test.cpp
tests/common/world/coordinate_test.cpp
tests/common/world/chunk_test.cpp
tests/common/network/net_host_test.cpp
tests/common/network/command_dispatcher_test.cpp

tests/common/util/obd_parser_test.cpp
tests/common/lua/script_engine_test.cpp

tests/client/lua/client_control_api_test.cpp
tests/client/lua/gui_widget_api_test.cpp

tests/client_server_tests.cpp
)

include_dirs(tests)
Expand Down
144 changes: 144 additions & 0 deletions docs/Adding-C++-Network-Events(Server to Client).md
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Adding new network events

This is a step-by-step guide on adding new network events that are sent from the server side, to be handled by the client side.

For example, updating the positions of entities on the client, by sending a packet from the server

## Step 1 - Add the event to the enum class

1. Go to (TODO: Add link) `src/common/network/net_command.h`

2. Add to either `ClientCommand` or `ServerCommand`

a. `ClientCommand` is for sending a message FROM the server TO the client

b. `ServerCommand` is for sending a message FROM the client TO the server

3. In this case, it is a `ClientCommand`. Add the enum, and explain what data will be sent in a comment

Example:
```cpp
enum class ClientCommand : command_t {
...
// Update entities states (position and rotation)
// u32: The number of entities to update
// [Loop this]
// u32: The ID of the entity
// float[3]: The position of the entity
// float[3]: The rotation of the entity
UpdateEntityStates,
```
## Step 2 - Add a function to the client class for handling the event
1. Go to (TODO Add link) `src/client/network/client_packet_handler.cpp` and (TODO Add link) `src/client/network/client.h`
2. In the header file, find the `void on<ClientCommand>(ClientPacket& packet);` function declarations and add your one here, keeping it in alphabetical order
3. In this case, it would be `void onUpdateEntityStates(ClientPacket& packet);`
4. Define your function in the source file, in this case it would be
```cpp
void Client::onUpdateEntityStates(ClientPacket& packet)
{
//...
}
```

## Step 3 - Read the packet

1. Read the data from the packet, you can see the other functions to understand how the interface of `ClientPacket` works (`auto data = packet.read<type>()`)

2. For example, for this you would read a u32 for the entity count, loop through it "count" times, updating the entities as you go:

```cpp
u32 count = packet.read<u32>();
for (u32 i = 0; i < count; i++) {
auto entId = packet.read<u32>();
auto entPosition = packet.read<glm::vec3>();
auto entRotation = packet.read<glm::vec3>();
mp_world->updateEntity(entId, entPosition, entRotation);
}
```
3. If needed, you would probably have to add the functionality to do whatever your event is handling (eg I had to add the update entity function to the ClientWorld class for this one)
## Step 4 - Listen for the packet
1. In the `client.cpp` file, find the `handlePacket` function
2. You'll see a switch case, simply add a `case` for the new packet type, calling the new function; keeping things in alphabetical order and alligned eg
```cpp
void Client::handlePacket(ClientPacket& packet)
{
using Cmd = ClientCommand;
// ....
case Cmd::UpdateEntityStates: onUpdateEntityStates (packet); break;
// ....
```

## Step 5 - Write functions to create a packet on the server

1. Go to (TODO Add link) `src/server/network/` folder.

2. Depending on the packet type depends where the function to create the packet is created.

3. If it is client-specific, then it would go into the `ClientSession` class (`client_session.h` and `client_session.cpp`)

3. In this case, it is a broadcast to all clients, so it goes in the `Server` class (`server.h` and `server.cpp`)

4. For a broadcast, name the function `broadcast<ClientCommand name>`, eg this case would be `void broadcastEntityStates();`

5. Again, define it in the source file:

```cpp
void Server::broadcastEntityStates()
{

}
```

## Step 6 - Send the packet

1. In the function body, create a ServerPacket, where the first parameter is the command name and the second parameter is `m_salt`

2. Eg, in this case it would be like ` ServerPacket packet(ClientCommand::UpdateEntityStates, m_salt);
`

3. Write some data to the packet. Usually, this would be passed in via the function parameters

4. In this case, I already have a function to serialise packets, so I will just call that

```cpp
mp_world->serialiseEntities(packet, 0);
```
5. Send the packet. For a broadcast, this is like:
```
broadcastToPeers(m_host.handle, packet.get());
```

## Step 7 - Call your new function from somewhere on the server

1. The server is owned by the ServerLauncher class, and maybe you could call it from the server loop, for example:

```cpp

void ServerLauncher::launch()
{
// ...
while (m_isServerRunning) {
// ...
m_server.broadcastEntityStates();
// ...
}
}
```

2. Done

# END
16 changes: 9 additions & 7 deletions game/client/menus/join_world_menu.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ local function onCreate(overlay)
menu:setBackground(backgroundTexture)

local serverIpBox = menu:addTextBox("Server IP", "Enter server IP...")
serverIpBox.text = "178.62.64.146"
--serverIpBox.text = "178.62.64.146"
serverIpBox.text = "127.0.0.1"

local label = menu:addLabel()
label.text = "This will either automatically register \nyou to the server, or log you in."
label.textSize = 35

menu:pad(45)

local usernameBox = menu:addTextBox("Username", "Enter username...")
local passwordBox = menu:addTextBox("Password", "Enter password...")
--local usernameBox = menu:addTextBox("Username", "Enter username...")

passwordBox:hideInput()
--local passwordBox = menu:addTextBox("Password", "Enter password...")
--passwordBox:hideInput()

local joinButton = menu:addButton("Join World")

Expand All @@ -29,11 +30,12 @@ local function onCreate(overlay)

joinButton.onClick = function()
local serverIp = serverIpBox:getText()
local username = usernameBox:getText()
local password = passwordBox:getText()
-- local username = usernameBox:getText()
-- local password = passwordBox:getText()
if string.len(serverIp) > 0 then
game.gui():change("transition", { message = "Joining World" } )
game.control():joinGame(serverIp, username, password)
--game.control():joinGame(serverIp, username, password)
game.control():joinGame(serverIp, "", "")
end
end
end
Expand Down
16 changes: 10 additions & 6 deletions src/client/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

add_library(ob-client
input/keyboard.cpp
world/chunk_mesh.cpp
world/chunk_mesh_generation.cpp
maths.cpp

gl/textures.cpp
gl/shader.cpp
Expand All @@ -15,8 +12,13 @@ add_library(ob-client

client_state_controller.cpp
client_engine.cpp
client.cpp
game.cpp

game/game.cpp
game/game_def.cpp
game/game_type.cpp
game/chunk_mesh.cpp
game/chunk_mesh_generation.cpp
game/client_world.cpp

lua/client_lua_callback.cpp
lua/gui_api.cpp
Expand All @@ -41,8 +43,10 @@ add_library(ob-client

window.cpp

network/client_commands.cpp
network/client.cpp
network/client_packet_handling.cpp

renderer/camera.cpp
renderer/gui_renderer.cpp
renderer/chunk_renderer.cpp
)
Expand Down

0 comments on commit 2861497

Please sign in to comment.