adding server

This commit is contained in:
AleaJactaEst 2023-10-22 20:30:36 +02:00
parent f552ebc9f6
commit 3816f3ca6e
6 changed files with 1411 additions and 0 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.rust/
server/target/

18
LICENCE.txt Normal file
View file

@ -0,0 +1,18 @@
Server Rust/Client Godot - Simple Multiplayer
Copyright (C) 2023 AleaJactaEst
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

609
server/Cargo.lock generated Normal file
View file

@ -0,0 +1,609 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bindgen"
version = "0.65.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfdf7b466f9a4903edc73f95d6d2bcd5baf8ae620638762244d3f60143643cc5"
dependencies = [
"bitflags 1.3.2",
"cexpr",
"clang-sys",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"syn",
"which",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07"
[[package]]
name = "bumpalo"
version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cc"
version = "1.0.83"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
dependencies = [
"libc",
]
[[package]]
name = "cexpr"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
dependencies = [
"nom",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"wasm-bindgen",
"windows-targets",
]
[[package]]
name = "clang-sys"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c688fc74432808e3eb684cae8830a86be1d66a2bd58e1f248ed0960a590baf6f"
dependencies = [
"glob",
"libc",
"libloading",
]
[[package]]
name = "cmake"
version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
dependencies = [
"cc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa"
[[package]]
name = "either"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
[[package]]
name = "enet"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd5c84ebdecb28194d15e063436a4b7863546a9dea268aee131ca23dbb2a21ac"
dependencies = [
"enet-sys",
"thiserror",
]
[[package]]
name = "enet-sys"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4580f5cb34ba20a73d05e26876f05fd3830a8959fb594b1ecb4d9ddac2eec77"
dependencies = [
"bindgen",
"cmake",
]
[[package]]
name = "errno"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "glob"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "home"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb"
dependencies = [
"windows-sys",
]
[[package]]
name = "iana-time-zone"
version = "0.1.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "js-sys"
version = "0.3.64"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c5f195fe497f702db0f318b07fdd68edb16955aed830df8363d837542f8f935a"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
[[package]]
name = "libc"
version = "0.2.149"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
[[package]]
name = "libloading"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b67380fd3b2fbe7527a606e18729d21c6f3951633d0500574c4dc22d2d638b9f"
dependencies = [
"cfg-if",
"winapi",
]
[[package]]
name = "linux-raw-sys"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
[[package]]
name = "log"
version = "0.4.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "memchr"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "minimal-lexical"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
[[package]]
name = "nom"
version = "7.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
dependencies = [
"memchr",
"minimal-lexical",
]
[[package]]
name = "num-traits"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]]
name = "prettyplease"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
dependencies = [
"proc-macro2",
"syn",
]
[[package]]
name = "proc-macro2"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
[[package]]
name = "regex"
version = "1.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]]
name = "rustix"
version = "0.38.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "745ecfa778e66b2b63c88a61cb36e0eea109e803b0b86bf9879fbc77c70e86ed"
dependencies = [
"bitflags 2.4.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]]
name = "server"
version = "0.1.0"
dependencies = [
"anyhow",
"byteorder",
"chrono",
"enet",
"log",
]
[[package]]
name = "shlex"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380"
[[package]]
name = "syn"
version = "2.0.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "thiserror"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1177e8c6d7ede7afde3585fd2513e611227efd6481bd78d2e82ba1ce16557ed4"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "unicode-ident"
version = "1.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
[[package]]
name = "wasm-bindgen"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7706a72ab36d8cb1f80ffbf0e071533974a60d0a308d01a5d0375bf60499a342"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ef2b6d3c510e9625e5fe6f509ab07d66a760f0885d858736483c32ed7809abd"
dependencies = [
"bumpalo",
"log",
"once_cell",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dee495e55982a3bd48105a7b947fd2a9b4a8ae3010041b9e0faab3f9cd028f1d"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
[[package]]
name = "which"
version = "4.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
dependencies = [
"either",
"home",
"once_cell",
"rustix",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.51.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.48.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
[[package]]
name = "windows_aarch64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
[[package]]
name = "windows_i686_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
[[package]]
name = "windows_i686_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
[[package]]
name = "windows_x86_64_gnu"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
[[package]]
name = "windows_x86_64_msvc"
version = "0.48.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"

13
server/Cargo.toml Normal file
View file

@ -0,0 +1,13 @@
[package]
name = "server"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
enet = "0.3.0"
anyhow = "1.0.56"
log = "0.4.20"
chrono = "0.4.31"
byteorder = "1.5.0"

656
server/src/main.rs Normal file
View file

@ -0,0 +1,656 @@
extern crate enet;
/*
Server minimal
Author : Aleajactaest
Created : 10 October 2023
Build:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
cargo build
target/debug/server-rust
*/
use std::net::Ipv4Addr;
use log::{debug, error, info, trace, warn, Level, LevelFilter, Metadata, Record, SetLoggerError};
use anyhow::Context;
use enet::*;
use std::*;
use chrono::Utc;
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt};
struct ServerLogger;
impl log::Log for ServerLogger {
fn enabled(&self, metadata: &Metadata) -> bool {
metadata.level() <= Level::Info
}
fn log(&self, record: &Record) {
//if self.enabled(record.metadata()) {
println!("{} [ {:5} ] {}", Utc::now().format("%Y-%m-%dT%H:%M:%SZ"), record.level(), record.args());
//}
}
fn flush(&self) {}
}
static LOGGER: ServerLogger = ServerLogger;
pub fn loginit(level:LevelFilter) -> Result<(), SetLoggerError> {
log::set_logger(&LOGGER)
.map(|()| log::set_max_level(level))
}
//const MAX_USER:usize = 100;
fn push_u64(data:&mut Vec<u8>, value:u64) {
let mut buf = [0; 8];
LittleEndian::write_u64(&mut buf, value);
data.push(buf[0]);
data.push(buf[1]);
data.push(buf[2]);
data.push(buf[3]);
data.push(buf[4]);
data.push(buf[5]);
data.push(buf[6]);
data.push(buf[7]);
}
fn push_f64(data:&mut Vec<u8>, value:f64) {
let mut buf = [0; 8];
LittleEndian::write_f64(&mut buf, value);
data.push(buf[0]);
data.push(buf[1]);
data.push(buf[2]);
data.push(buf[3]);
data.push(buf[4]);
data.push(buf[5]);
data.push(buf[6]);
data.push(buf[7]);
}
/*
enum Simple {
Error(String),
Okay,
Foo([u32; 5]),
}
impl Clone for Simple {
fn clone(&self) -> Simple {
match self {
Error(a) => Error(a.to_string()),
Okay => Okay,
Foo(a) => Foo(a.clone()),
}
}
}
*/
enum StateUsers {
NotDefined,
Inactive,
UpdateUser,
UpdateAddress,
Error,
Done,
}
struct Position {
x: f64,
y: f64,
z: f64,
}
/*
* User
*/
struct User {
active: bool,
username: String,
address: Address,
id: u64,
x: f64,
y: f64,
z: f64,
position_updated: bool
}
impl User {
/*
pub fn new() -> User {
Self {
active: false,
username: "".to_string(),
address: Address::new( Ipv4Addr::new(0,0,0,0), 0 )
}
}
*/
pub fn set_inactive(&mut self) {
self.active = false;
}
pub fn set_active(&mut self) {
self.active = true;
}
pub fn update_username(&mut self, username: String, id:u64) {
self.username = username;
self.id = id;
}
pub fn update_address(&mut self, address: Address, id:u64) {
self.address = address;
self.id = id;
}
pub fn clear_username(&mut self) {
self.username = "".to_string();
}
pub fn clear_address(&mut self) {
self.address = Address::new(Ipv4Addr::new(0, 0, 0, 0), 0);
}
pub fn clear_position_updated(&mut self) {
self.position_updated = false;
}
pub fn update_pos(&mut self, x:f64, y:f64, z:f64) {
if self.x != x {
self.x = x;
self.position_updated = true;
}
if self.y != y {
self.y = y;
self.position_updated = true;
}
if self.z != z {
self.z = z;
self.position_updated = true;
}
}
pub fn get_position(&mut self) -> Position {
let pos:Position = Position{x: self.x, y: self.y, z: self.z};
return pos;
}
pub fn push_packet(&self, data:&mut Vec<u8>) {
push_u64(data, self.id);
push_f64(data, self.x);
push_f64(data, self.y);
push_f64(data, self.z);
}
/*
pub fn get_packet(&mut self) -> Vec<u8> {
let mut data:Vec<u8> = Vec::new();
push_u64(&mut data, self.id);
push_f64(&mut data, self.x);
push_f64(&mut data, self.y);
push_f64(&mut data, self.z);
data
}
*/
}
impl std::fmt::Display for User {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "id:{} user:{} active:{} address:{}:{} ({}:{}:{})", self.id, self.username, self.active, self.address.ip(), self.address.port(), self.x, self.y, self.z)
}
}
/*
* Users
*/
struct Users {
users: Vec<User>,
lastid: u64,
}
impl Users {
pub fn new() -> Users {
Self {
lastid: 0,
users: Vec::new()
}
}
/*
pub fn search(&self, username:String) -> bool {
for user in &self.users {
println!("{}", user);
if user.username == username {
return true;
}
}
return false;
}
*/
pub fn search_me(&self, username:String, address: Address) -> StateUsers {
let mut nb_user:u8 = 0;
let mut nb_address:u8 = 0;
let mut user_address:bool = false;
//let mut is_active:bool = false;
let mut user_active:bool = false;
let mut address_active:bool = false;
let mut cur:StateUsers = StateUsers::NotDefined;
// check user & address
for user in &self.users {
if user.username == username {
nb_user+=1;
if user.active {
user_active = true;
}
if user.address == address {
user_address = true;
cur = match cur {
StateUsers::NotDefined => {
if user.active {
trace!("User:Ok, Address:Ok, Active:True");
StateUsers::Done
} else {
trace!("User:Ok, Address:Ok, Active:False");
StateUsers::Inactive
}
}
_ => {
trace!("User:Ok, Address:Ok, But already checked ?");
StateUsers::Error
}
};
}
}
if user.address == address {
nb_address+=1;
if user.active {
address_active = true;
}
}
}
// check
if nb_user == 0 && nb_address == 0 {
trace!("NotDefined: User: not define, Address: not define");
return StateUsers::NotDefined;
} else if nb_user == 1 && nb_address == 0 {
trace!("UpdateAddress: User: {}, Address: {}", nb_user, nb_address);
return StateUsers::UpdateAddress;
} else if nb_user == 0 && nb_address == 1 {
trace!("UpdateUser: User: {}, Address: {}", nb_user, nb_address);
return StateUsers::UpdateUser;
} else if nb_user == 1 && nb_address == 1 {
if user_address {
return cur;
} else if user_active && ! address_active {
trace!("UpdateUser: User: not define, Address: Ok");
return StateUsers::UpdateUser;
} else if address_active && ! user_active {
trace!("UpdateAddress: User: Ok, Address: not define");
return StateUsers::UpdateAddress;
} else {
trace!("Error: User: {}, Address: {}", nb_user, nb_address);
return StateUsers::Error;
}
}
trace!("? User: {}, Address: {}", nb_user, nb_address);
return StateUsers::Error;
}
pub fn get_new_id(&mut self) -> u64 {
self.lastid += 1;
self.lastid
}
pub fn add(&mut self, username:String, address: Address) -> u64 {
let id = self.get_new_id();
self.users.push( User { active: true, username:username, address: address, id: id, x: 0.0, y: 10.0, z:0.0, position_updated:true} );
id
}
pub fn update_pos(&mut self, address: Address, x:f64, y:f64, z:f64) {
for user in self.users.iter_mut() {
if user.address == address {
user.update_pos(x, y, z);
}
}
}
pub fn set_inactive(&mut self, address: Address) -> u64 {
for user in self.users.iter_mut() {
if user.address == address {
user.set_inactive();
return user.id;
}
}
return 0;
}
pub fn set_active(&mut self, address: Address) -> u64 {
for user in self.users.iter_mut() {
if user.address == address {
user.set_active();
return user.id;
}
}
return 0;
}
pub fn update_username(&mut self, username:String, address: Address) -> u64 {
let id = self.get_new_id();
for user in self.users.iter_mut() {
if user.address == address {
user.update_username(username.clone(), id);
user.set_active();
} else if user.username == username {
user.clear_username();
}
}
id
}
pub fn update_address(&mut self, username:String, address: Address) -> u64 {
let id = self.get_new_id();
for user in self.users.iter_mut() {
if user.username == username {
user.update_address(address.clone(), id);
user.set_active();
} else if user.address == address {
user.clear_address();
}
}
id
}
pub fn get_id(&mut self, address: Address) -> u64 {
for user in &self.users {
if user.address == address {
return user.id;
}
}
return 0;
}
pub fn get_user(&mut self, address: Address) -> Result<&User, &'static str> {
for user in &self.users {
if user.address == address {
return Ok(user.clone());
}
}
error!("invalid address {}:{}", address.ip(), address.port());
Err("invalid address")
}
pub fn push_packet(&self, data:&mut Vec<u8>) -> u8 {
let mut nb:u8 = 0;
for user in &self.users {
if user.active && user.position_updated {
user.push_packet(data);
nb += 1;
}
}
nb
}
pub fn clear_position_updated(&mut self) {
for user in self.users.iter_mut() {
if user.position_updated {
user.clear_position_updated();
}
}
}
}
impl std::fmt::Display for Users {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "len: {} -- ", self.users.len()).unwrap();
for user in self.users.iter() {
write!(f, "[{}] ", user).unwrap();
}
Ok(())
}
}
/*
impl std::fmt::Display for Vec<Users> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
for user in self.users.iter() {
write!(f, "{}, ", self.users)
}
}
}
*/
/*
impl Users {
pub fn print(&self) {
println!("len: {}", self.users.len());
for user in self.users {
println!("active:{} (user:{} address:{}:{})",user.active, user.username, user.address.ip(), user.address.port());
}
}
}
*/
/*
impl Copy for User { }
impl Clone for User {
fn clone(&self) -> User {
match self {
active => active.clone(),
username => username.clone(),
address => address.clone(),
}
}
}
*/
/*
* Send a message
*/
fn send_message(sender:Peer<()>, data: &[u8] ) -> Result<(), Error> {
let mut peer = sender.clone();
peer.send_packet (
Packet::new(data, PacketMode::ReliableSequenced).unwrap(),
1,
)
}
/*
fn send_message_connect_ok(sender:Peer<()>, id:u64, x:f64, y:f64, z:f64) -> Result<(), Error> {
let mut data:Vec<u8> = Vec::new();
data.push(1); // return connexion request
data.push(0); // return ok
// get_packet
push_u64(&mut data, id);
push_f64(&mut data, x);
push_f64(&mut data, y);
push_f64(&mut data, z);
let c: &[u8] = &data;
send_message(sender, c)
}
*/
fn send_message_connect_ok(sender:Peer<()>, user: &User) -> Result<(), Error> {
let mut data:Vec<u8> = Vec::new();
data.push(1); // return connexion request
data.push(0); // return ok
user.push_packet(&mut data);
let c: &[u8] = &data;
send_message(sender, c)
}
fn send_message_connect_ko(sender:Peer<()>) -> Result<(), Error> {
let mut data:Vec<u8> = Vec::new();
data.push(1); // return connexion request
data.push(2); // return ko
let c: &[u8] = &data;
send_message(sender, c)
}
fn show(data: &[u8]) -> String {
data.iter().map(|b| format!("{:02X}", b)).collect::<Vec<_>>().join(", ")
}
/*
* Main
*/
fn main() -> anyhow::Result<()> {
let enet = Enet::new().context("could not initialize ENet")?;
//env_logger::init();
loginit(LevelFilter::Trace).unwrap();
// simple_logging::log_to_stderr(LevelFilter::Info);
/*
debug!("Debug");
trace!("Trace");
info!("Enet initialized");
warn!("Enet initialized");
error!("Enet initialized");
*/
let local_addr = Address::new(Ipv4Addr::LOCALHOST, 33333);
let mut host = enet
.create_host::<()>(
Some(&local_addr),
10,
ChannelLimit::Maximum,
BandwidthLimit::Unlimited,
BandwidthLimit::Unlimited,
)
.context("could not create host")?;
//let mut users: [User; MAX_USER] = [User { active: false, username:"".to_string(), address: Address::new( Ipv4Addr::new(0,0,0,0), 0)}; MAX_USER];
let mut users:Users = Users::new() ;
info!("Started");
loop {
trace!("users: {}", users);
match host.service(1000).context("service failed")? {
Some(Event::Connect(_)) => debug!("new connection!"),
Some(Event::Disconnect(ref sender, _)) => {
users.set_inactive(sender.address());
debug!("disconnect!");
},
Some(Event::Receive {
ref sender,
channel_id,
ref packet
}) => {
debug!(
"got packet on channel {}, len: '{}' (who:{}:{})",
channel_id,
packet.data().len(),
sender.address().ip(),
sender.address().port()
);
match channel_id {
1 => {
let cmd = packet.data()[0];
let size = packet.data()[1] as usize;
let player_name = &packet.data()[2..=size+1];
let s = match str::from_utf8(player_name) {
Ok(v) => v,
Err(_e) => "",
};
trace!("cmd: {} size:{} name:{} '{}'", cmd, size, player_name.len(), s);
if s.to_string() == "Interdit" || s.to_string() == "" {
warn!("Received forbidden account '{}'", s);
send_message_connect_ko(sender.clone()).unwrap();
continue;
}
let check = users.search_me(s.to_string(), sender.address());
match check {
StateUsers::NotDefined => {
debug!("NotDefined");
let _id = users.add(s.to_string(), sender.address());
let ret = users.get_user(sender.address());
match ret {
Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(),
Err(_e) => {},
};
}
StateUsers::Inactive => {
debug!("Inactive");
let _id = users.set_active(sender.address());
let ret = users.get_user(sender.address());
match ret {
Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(),
Err(_e) => {},
};
}
StateUsers::UpdateUser => {
debug!("UpdateUser");
let _id = users.update_username(s.to_string(), sender.address());
let ret = users.get_user(sender.address());
match ret {
Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(),
Err(_e) => {},
};
}
StateUsers::UpdateAddress => {
debug!("UpdateAddress");
let _id = users.update_address(s.to_string(), sender.address());
let ret = users.get_user(sender.address());
match ret {
Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(),
Err(_e) => {},
};
}
StateUsers::Error => {
error!("Bad request from {}:{}", sender.address().ip(),sender.address().port());
send_message_connect_ko(sender.clone()).unwrap();
}
StateUsers::Done => {
debug!("Done");
let _id = users.get_id(sender.address());
let ret = users.get_user(sender.address());
match ret {
Ok(user) => send_message_connect_ok(sender.clone(), user).unwrap(),
Err(_e) => {},
};
}
}
}
2 => {
let mut xbytes: &[u8] = &packet.data()[0..8];
let x = xbytes.read_f64::<LittleEndian>().unwrap();
let mut ybytes: &[u8] = &packet.data()[8..16];
let y = ybytes.read_f64::<LittleEndian>().unwrap();
let mut zbytes: &[u8] = &packet.data()[16..24];
let z = zbytes.read_f64::<LittleEndian>().unwrap();
users.update_pos(sender.address(), x, y, z);
}
_ => {
let mut peer = sender.clone();
peer.send_packet (
Packet::new(b"youpia", PacketMode::ReliableSequenced).unwrap(),
1,
)
.context("sending packet failed")?;
}
}
},
_ => (),
}
// Send all player, position other player
{
let mut data:Vec<u8> = Vec::new();
let mut data2:Vec<u8> = Vec::new();
data.push(3); // return connexion request
let nb:u8 = users.push_packet(&mut data2);
data.push(nb); // number user
data.append(&mut data2);
let c: &[u8] = &data;
if nb > 0 {
for peer in host.peers() {
if peer.state() == PeerState::Connected {
trace!("peer: {}:{}", peer.address().ip(), peer.address().port());
send_message(peer, c);
}
}
users.clear_position_updated();
}
}
/*
for peer in host.peers() {
if peer.state() == PeerState::Connected {
trace!("peer: {}:{}", peer.address().ip(), peer.address().port());
let mut data:Vec<u8> = Vec::new();
let mut data2:Vec<u8> = Vec::new();
data.push(3); // return connexion request
let nb:u8 = users.push_packet(&mut data2);
data.push(nb); // number user
data.append(&mut data2);
let c: &[u8] = &data;
send_message(peer, c);
}
}
*/
}
}

113
start-bazar-server.sh Executable file
View file

@ -0,0 +1,113 @@
#!/bin/bash
#
# Script to launch server
#
# Copyright (C) 2023 AleaJactaEst
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
declare DEBUG=0
declare HELP=0
declare BUILD=0
declare WORKDIR="$(dirname $(readlink -f $0))"
declare RUSTDIR="$WORKDIR/.rust"
declare SERVERDIR="$WORKDIR/server"
function msg_debug()
{
if [ $DEBUG -ne 0 ]
then
echo "### DEBUG : $*" >&2
fi
}
function msg_info()
{
echo "--- INFO : $*" >&2
}
function msg_error()
{
echo "*** ERROR : $*" >&2
}
function byebye()
{
local CODE=$?
if [ $CODE -ne 0 ]
then
msg_error "return code:$code"
else
msg_info "End"
fi
exit $CODE
}
while getopts hdb flag
do
case "${flag}" in
h) HELP=1;;
d) DEBUG=1;;
b) BUILD=1;;
*) HELP=1;;
esac
done
if [[ $HELP -ne 0 ]]
then
cat << EOF
$(basename $0) [Option] : Donwload Launch Godot
Option:
-h : Show help
-d : Show debug message
-b : (re)build program
EOF
exit 1
fi
trap byebye EXIT
msg_info "Start"
msg_debug "WORKDIR:$WORKDIR"
if [[ ($BUILD -ne 0) || (! -x $SERVERDIR/target/debug/server) ]]
then
export CARGO_HOME="$RUSTDIR/.cargo"
export RUSTUP_HOME="$RUSTDIR/.rustup"
mkdir -p $RUSTDIR
if [ ! -f $RUSTDIR/install.sh ]
then
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs > $RUSTDIR/install.sh
fi
if [ ! -f $RUSTDIR/.cargo/env ]
then
sh .rust/install.sh -t $RUSTDIR/.cargo --no-modify-path -y
# curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -h
fi
if [ -f $RUSTDIR/.cargo/env ]
then
source $RUSTDIR/.cargo/env
cd $SERVERDIR
cargo build
else
msg_error "Error to load envi rust"
exit 2
fi
fi
$SERVERDIR/target/debug/server
# END (call function byebye)