Compare commits
2 Commits
860b319a03
...
277d25a820
| Author | SHA256 | Date | |
|---|---|---|---|
|
277d25a820
|
|||
|
1b2d6bdac2
|
21
.env.example
Executable file
21
.env.example
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
LOG_LEVEL=info
|
||||||
|
REDIS_URL=redis://:super_safe_password@127.0.0.1:6379/0
|
||||||
|
LISTEN_ADDR=0.0.0.0
|
||||||
|
CONSUL_URL=http://consul:8500
|
||||||
|
POSTGRES_USER=osirose
|
||||||
|
POSTGRES_PASSWORD=super_safe_postgres_password
|
||||||
|
POSTGRES_DB=osirose
|
||||||
|
|
||||||
|
# Define service addresses for consul.
|
||||||
|
# This will set the service address in consul to what ever is placed here.
|
||||||
|
# This can be a IP address or the container name in docker
|
||||||
|
AUTH_SERVICE_ADDR=auth-service
|
||||||
|
API_SERVICE_ADDR=api-service
|
||||||
|
CHARACTER_SERVICE_ADDR=character-service
|
||||||
|
DATABASE_SERVICE_ADDR=database-service
|
||||||
|
PACKET_SERVICE_ADDR=packet-service
|
||||||
|
WORLD_SERVICE_ADDR=world-service
|
||||||
|
|
||||||
|
#<Service Name>_SERVICE_PORT=<PORT> # Replace Service name with the service and port with the port you want to run it on. Ex. AUTH_SERVICE_PORT=30000
|
||||||
|
#JWT_SECRET=safe_jwt_secret # This is only used for auth-service and is required.
|
||||||
|
#HEALTH_CHECK_PORT=8080 # This will change the health check port for the services
|
||||||
98
docker-compose.yml
Executable file
98
docker-compose.yml
Executable file
@@ -0,0 +1,98 @@
|
|||||||
|
services:
|
||||||
|
auth-service:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./auth-service/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "50051:50051"
|
||||||
|
env_file:
|
||||||
|
- ./auth-service/.env
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
- HEALTH_CHECK_PORT=8080
|
||||||
|
depends_on:
|
||||||
|
- database-service
|
||||||
|
- consul
|
||||||
|
|
||||||
|
api-service:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./api-service/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
env_file:
|
||||||
|
- ./api-service/.env
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- auth-service
|
||||||
|
- consul
|
||||||
|
|
||||||
|
database-service:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./database-service/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "50052:50052"
|
||||||
|
env_file:
|
||||||
|
- ./database-service/.env
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- db
|
||||||
|
- consul
|
||||||
|
|
||||||
|
character-service:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./character-service/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "50053:50053"
|
||||||
|
env_file:
|
||||||
|
- ./character-service/.env
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- auth-service
|
||||||
|
- consul
|
||||||
|
|
||||||
|
world-service:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./world-service/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "50054:50054"
|
||||||
|
env_file:
|
||||||
|
- ./world-service/.env
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- auth-service
|
||||||
|
- consul
|
||||||
|
|
||||||
|
packet-service:
|
||||||
|
build:
|
||||||
|
context: ./
|
||||||
|
dockerfile: ./packet-service/Dockerfile
|
||||||
|
ports:
|
||||||
|
- "4000:4000"
|
||||||
|
env_file:
|
||||||
|
- ./packet-service/.env
|
||||||
|
- .env
|
||||||
|
depends_on:
|
||||||
|
- auth-service
|
||||||
|
- consul
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:17
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "5432:5432"
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/postgresql/data
|
||||||
|
|
||||||
|
consul:
|
||||||
|
image: consul:1.15.4
|
||||||
|
command: agent -dev -client=0.0.0.0
|
||||||
|
ports:
|
||||||
|
- "8500:8500"
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
70
launcher/src/launcher.rs
Normal file
70
launcher/src/launcher.rs
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
use crate::{format_shell_command, wait_for_keypress};
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::env;
|
||||||
|
use std::process::{exit, Command, Stdio};
|
||||||
|
use tracing::{debug, error, info, warn};
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
pub(crate) fn launch_game(url: String) {
|
||||||
|
let exe_dir_path = env::current_exe().unwrap().parent().unwrap().to_path_buf();
|
||||||
|
|
||||||
|
// Change the working directory
|
||||||
|
if let Err(e) = env::set_current_dir(exe_dir_path) {
|
||||||
|
error!("Failed to set working directory: {}", e);
|
||||||
|
wait_for_keypress();
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse the URL
|
||||||
|
match Url::parse(&url) {
|
||||||
|
Ok(parsed_url) => {
|
||||||
|
let params = parsed_url.query_pairs();
|
||||||
|
let game_executable = "./TRose.exe";
|
||||||
|
let mut command = Command::new(game_executable);
|
||||||
|
command.arg("@TRIGGER_SOFT@");
|
||||||
|
|
||||||
|
let mut is_direct = false;
|
||||||
|
for (key, value) in params {
|
||||||
|
debug!("Query pairs: [{}, {}]", key, value);
|
||||||
|
|
||||||
|
match key {
|
||||||
|
Cow::Borrowed("ip") => {
|
||||||
|
command.arg("_server").arg(value.to_string());
|
||||||
|
}
|
||||||
|
Cow::Borrowed("port") => {
|
||||||
|
command.arg("_port").arg(value.to_string());
|
||||||
|
}
|
||||||
|
Cow::Borrowed("otp") => {
|
||||||
|
is_direct = true;
|
||||||
|
command.arg("_direct").arg("_otp").arg(value.to_string());
|
||||||
|
}
|
||||||
|
Cow::Borrowed("username") => {
|
||||||
|
command.arg("_userid").arg(value.to_string());
|
||||||
|
}
|
||||||
|
Cow::Borrowed("password") => {
|
||||||
|
if !is_direct {
|
||||||
|
command.arg("_pass").arg(value.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
warn!("Unexpected parameter: [{}, {}]", key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
command
|
||||||
|
.stdin(Stdio::null())
|
||||||
|
.stdout(Stdio::null())
|
||||||
|
.stderr(Stdio::null());
|
||||||
|
|
||||||
|
info!("Executing: {:?}", format_shell_command(&command));
|
||||||
|
|
||||||
|
// Check if the game launched successfully
|
||||||
|
match command.spawn() {
|
||||||
|
Ok(_) => info!("Game launched successfully!"),
|
||||||
|
Err(e) => error!("Failed to launch the game: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => error!("Failed to parse URL: {}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
use std::path::{Path, PathBuf};
|
mod launcher;
|
||||||
use std::process::{exit, Command, Stdio};
|
|
||||||
use clap::{Parser, Subcommand};
|
use clap::{Parser, Subcommand};
|
||||||
use std::{env, io};
|
use std::process::{Command};
|
||||||
|
use std::{io};
|
||||||
use tracing::{debug, error, info, Level};
|
use tracing::{debug, error, info, Level};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(version, about, long_about = None)]
|
#[command(version, about, long_about = None)]
|
||||||
@@ -12,17 +12,15 @@ struct Args {
|
|||||||
action: Commands,
|
action: Commands,
|
||||||
|
|
||||||
#[arg(short, long, action = clap::ArgAction::Count)]
|
#[arg(short, long, action = clap::ArgAction::Count)]
|
||||||
verbose: u8
|
verbose: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Subcommand, Debug)]
|
#[derive(Subcommand, Debug)]
|
||||||
enum Commands {
|
enum Commands {
|
||||||
#[command(name = "launch")]
|
#[command(name = "launch")]
|
||||||
Launch {
|
Launch { url: String },
|
||||||
url: String,
|
|
||||||
},
|
|
||||||
#[command(name = "update")]
|
#[command(name = "update")]
|
||||||
Update
|
Update,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
@@ -30,18 +28,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
let verbose = match args.verbose {
|
let verbose = match args.verbose {
|
||||||
0 => Level::INFO,
|
0 => Level::INFO,
|
||||||
1 => Level::DEBUG,
|
1 => Level::DEBUG,
|
||||||
_ => Level::TRACE
|
_ => Level::TRACE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set our logging level
|
||||||
tracing_subscriber::fmt().with_max_level(verbose).init();
|
tracing_subscriber::fmt().with_max_level(verbose).init();
|
||||||
|
|
||||||
let action = args.action;
|
let action = args.action;
|
||||||
|
|
||||||
match action {
|
match action {
|
||||||
Commands::Launch { url } => {
|
Commands::Launch { url } => {
|
||||||
debug!("launching with URL {}", url);
|
debug!("launching with URL {}", url);
|
||||||
launch_game(url);
|
launcher::launch_game(url);
|
||||||
},
|
}
|
||||||
Commands::Update => {
|
Commands::Update => {
|
||||||
error!("Update action not implemented");
|
error!("Update action not implemented");
|
||||||
return Err("Update action not implemented".into());
|
return Err("Update action not implemented".into());
|
||||||
@@ -51,88 +49,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn launch_game(url: String) {
|
|
||||||
|
|
||||||
let exe_dir_path = env::current_exe().unwrap().parent().unwrap().to_path_buf();
|
|
||||||
// let working_directory =
|
|
||||||
// env::var("GAME_CLIENT_PATH").unwrap_or_else(|_| "D:/rose_osirose-new-x64".to_string());
|
|
||||||
|
|
||||||
// Change the working directory
|
|
||||||
if let Err(e) = env::set_current_dir(exe_dir_path) {
|
|
||||||
error!("Failed to set working directory: {}", e);
|
|
||||||
wait_for_keypress();
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the URL
|
|
||||||
match Url::parse(&url) {
|
|
||||||
Ok(parsed_url) => {
|
|
||||||
// Extract the "otp" parameter
|
|
||||||
let otp = parsed_url
|
|
||||||
.query_pairs()
|
|
||||||
.find(|(key, _)| key == "otp")
|
|
||||||
.map(|(_, value)| value.to_string());
|
|
||||||
let ip = parsed_url
|
|
||||||
.query_pairs()
|
|
||||||
.find(|(key, _)| key == "ip")
|
|
||||||
.map(|(_, value)| value.to_string());
|
|
||||||
let username = parsed_url
|
|
||||||
.query_pairs()
|
|
||||||
.find(|(key, _)| key == "username")
|
|
||||||
.map(|(_, value)| value.to_string());
|
|
||||||
let port = parsed_url
|
|
||||||
.query_pairs()
|
|
||||||
.find(|(key, _)| key == "port")
|
|
||||||
.map(|(_, value)| value.to_string())
|
|
||||||
.unwrap_or("4000".to_string());
|
|
||||||
|
|
||||||
// Ensure required parameters are present
|
|
||||||
if otp.is_none() || ip.is_none() || username.is_none() {
|
|
||||||
error!("Missing required parameters: otp, ip, or username");
|
|
||||||
wait_for_keypress();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap the parameters
|
|
||||||
let otp = otp.unwrap();
|
|
||||||
let ip = ip.unwrap();
|
|
||||||
let username = username.unwrap();
|
|
||||||
|
|
||||||
info!("Launching game with:");
|
|
||||||
info!(" OTP: {}", otp);
|
|
||||||
info!(" IP: {}", ip);
|
|
||||||
info!(" Username: {}", username);
|
|
||||||
|
|
||||||
// Construct the game client command
|
|
||||||
let game_executable = "./TRose.exe";
|
|
||||||
let mut command = Command::new(game_executable);
|
|
||||||
command
|
|
||||||
.arg("@TRIGGER_SOFT@")
|
|
||||||
.arg("_direct")
|
|
||||||
.arg("_server")
|
|
||||||
.arg(ip)
|
|
||||||
.arg("_port")
|
|
||||||
.arg(port)
|
|
||||||
.arg("_userid")
|
|
||||||
.arg(username)
|
|
||||||
.arg("_otp")
|
|
||||||
.arg(otp)
|
|
||||||
.stdin(Stdio::null())
|
|
||||||
.stdout(Stdio::null())
|
|
||||||
.stderr(Stdio::null());
|
|
||||||
|
|
||||||
info!("Executing: {:?}", format_shell_command(&command));
|
|
||||||
|
|
||||||
// Check if the game launched successfully
|
|
||||||
match command.spawn() {
|
|
||||||
Ok(_) => info!("Game launched successfully!"),
|
|
||||||
Err(e) => error!("Failed to launch the game: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => error!("Failed to parse URL: {}", e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn wait_for_keypress() {
|
fn wait_for_keypress() {
|
||||||
// Wait for a keypress
|
// Wait for a keypress
|
||||||
info!("Press Enter to close the launcher...");
|
info!("Press Enter to close the launcher...");
|
||||||
@@ -147,4 +63,4 @@ fn format_shell_command(command: &Command) -> String {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
format!("{} {}", executable, args.join(" "))
|
format!("{} {}", executable, args.join(" "))
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user