A ansible/deploy.yaml => ansible/deploy.yaml +55 -0
@@ 0,0 1,55 @@
+- name: Deploy bleeding servers
+ hosts: starkingdoms_prod_servers_bleeding
+ vars:
+ api_token: "{{ lookup('community.general.random_string', length=24) }}"
+ jwt_signing_secret: "{{ lookup('community.general.random_string', length=24) }}"
+ db_user: starkingdoms-bleeding
+ db_pass: "{{ lookup('community.general.random_string', length=24) }}"
+ db_name: starkingdoms-bleeding
+ ws_port: 3000
+ version: bleeding
+ api_port: 8080
+ api_config_dir: /home/stk-deploy/config
+ db_data_dir: /home/stk-deploy/data
+ compose_dir: /home/stk-deploy
+ api_url: https://api.bleeding.starkingdoms.tk
+ game_url: https://bleeding.starkingdoms.tk
+ web_port: 8000
+ tasks:
+ - name: Ensure host connectivity
+ ansible.builtin.ping:
+ - name: Create configuration directory
+ ansible.builtin.file:
+ path: {{ api_config_dir }}
+ state: directory
+ mode: 0755
+ - name: Create data directory
+ ansible.builtin.file:
+ path: {{ db_data_dir }}
+ state: directory
+ mode: 0755
+ - name: Create API config file
+ ansible.builtin.template:
+ src: ../docker/config.jinja.toml
+ dest: "{{ api_config_dir }}/config.toml"
+ - name: Create docker-compose config file
+ ansible.builtin.template:
+ src: ../docker/docker-compose.jinja.yml
+ dest: "{{ compose_dir }}/docker-compose.yml"
+ - name: Start the server
+ ansible.builtin.shell:
+ cmd: docker-compose up -d
+ chdir: "{{ compose_dir }}"
+
+
+- name: Deploy beta servers
+ hosts: starkingdoms_prod_servers_beta
+ tasks:
+ - name: Ensure host connectivity
+ ansible.builtin.ping:
+
+- name: Deploy stable servers
+ hosts: starkingdoms_prod_servers_stable
+ tasks:
+ - name: Ensure host connectivity
+ ansible.builtin.ping:<
\ No newline at end of file
A ansible/inventory.yaml => ansible/inventory.yaml +23 -0
@@ 0,0 1,23 @@
+starkingdoms_prod_servers_stable:
+ hosts:
+ ghosteast1:
+ ansible_host: 10.17.4.2
+ ansible_user: stk-deploy
+
+starkingdoms_prod_servers_beta:
+ hosts:
+ east3:
+ ansible_host: 10.16.2.5
+ ansible_user: stk-deploy
+
+starkingdoms_prod_servers_bleeding:
+ hosts:
+ central1:
+ ansible_host: 10.16.1.1
+ ansible_user: stk-deploy
+
+starkingdoms_prod_servers:
+ children:
+ starkingdoms_prod_servers_stable:
+ starkingdoms_prod_servers_beta:
+ starkingdoms_prod_servers_bleeding:<
\ No newline at end of file
M client/index.html => client/index.html +103 -77
@@ 1,80 1,106 @@
<!DOCTYPE html>
<html lang="en-US">
-<head>
- <meta charset="utf-8" />
- <title>StarKingdoms.TK</title>
- <link rel="stylesheet" href="./static/index.css"/>
-</head>
-
-<body>
-<h1>StarKingdoms</h1>
-<fieldset class="joingamebox">
- <legend>Join Game</legend>
- <form action="/play.html" method="GET">
- <label for="server">Choose server</label>
- <select class="joingamecontent" name="server" id="server">
- <!-- Dynamically filled by the JS later in this file -->
- </select>
- <br>
- <label for="textures">Texture quality</label>
- <select class="joingamecontent" name="textures" id="textures">
- <option value="full">Full quality (May impact loading times)</option>
- <option selected value="375">Medium quality (Recommended)</option>
- <option value="125">Low quality</option>
- </select>
- <br>
- <label for="username">Username</label>
- <br>
- <input class="m-5px" type="text" name="username" id="username" required />
- <br>
- <button class="m-5px w-full">Launch!</button>
- <br>
- <p id="loginstatus">You are not logged in.</p>
- <button style="display: none;" id="logout">Log out</button>
- <a href="http://localhost:8080/select-realm" id="login">Click here to log in or change accounts.</a>
- </form>
-</fieldset>
-
-<script>
- let api_server = "http://localhost:8080";
- let servers = ["localhost:3000"];
-
- function server_url_to_ping_url(server) { return "http://" + server + "/ping" }
- function server_url_to_gateway_url(server) { return "ws://" + server + "/ws" }
-
- function load_server(server) {
- // ping the server to get server information
- fetch(server_url_to_ping_url(server)).then(response => {
- response.json().then(response => {
- let elem = document.createElement("option");
- elem.value = server_url_to_gateway_url(server);
- elem.text = `${response.description} - ${response.version.name} - ${response.players} online`;
- document.getElementById("server").appendChild(elem);
- })
- })
- }
-
- for (let i = 0; i < servers.length; i++) {
- load_server(servers[i]);
- }
-
- let query = new URLSearchParams(window.location.search);
-
- if (query.has("token") && query.has("user")) {
- window.localStorage.setItem("token", query.get("token"));
- window.localStorage.setItem("user", query.get("user"));
- }
-
- if (window.localStorage.getItem("token") !== null && window.localStorage.getItem("user") !== null) {
- document.getElementById("logout").style.setProperty("display", "block");
- document.getElementById("logout").addEventListener("click", () => {
- window.localStorage.clear();
- window.location.reload();
- })
- document.getElementById("loginstatus").innerText = `Logged in! (you are ${window.localStorage.getItem("user")})`;
- }
-
- document.getElementById("login").href = `${api_server}/select-realm`;
-</script>
-</body>
+ <head>
+ <meta charset="UTF-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+ <title>StarKingdoms</title>
+ </head>
+
+ <body>
+ <h1>StarKingdoms</h1>
+ <fieldset class="joingamebox">
+ <legend>Join Game</legend>
+ <form action="/play.html" method="GET">
+ <label for="server">Choose server</label>
+ <select class="joingamecontent" name="server" id="server">
+ <!-- Dynamically filled by the JS later in this file -->
+ </select>
+ <br>
+ <label for="textures">Texture quality</label>
+ <select class="joingamecontent" name="textures" id="textures">
+ <option value="full">Full quality (May impact loading times)</option>
+ <option selected value="375">Medium quality (Recommended)</option>
+ <option value="125">Low quality</option>
+ </select>
+ <br>
+ <label for="username">Username</label>
+ <br>
+ <input class="m-5px" type="text" name="username" id="username" required/>
+ <br>
+ <button class="m-5px w-full">Launch!</button>
+ <br>
+ <p id="loginstatus">You are not logged in.</p>
+ <button style="display: none;" id="logout">Log out</button>
+ <a href="http://localhost:8080/select-realm" id="login">Click here to log in or change accounts.</a>
+ </form>
+ </fieldset>
+
+
+ <script type="module">
+ let api_server = "http://localhost:8080";
+ let servers = ["localhost:3000"];
+
+ function server_url_to_ping_url(server) {
+ return "http://" + server + "/ping"
+ }
+
+ function server_url_to_gateway_url(server) {
+ return "ws://" + server + "/ws"
+ }
+
+ function load_server(server) {
+ // ping the server to get server information
+ fetch(server_url_to_ping_url(server)).then(response => {
+ response.json().then(response => {
+ let elem = document.createElement("option");
+ elem.value = server_url_to_gateway_url(server);
+ elem.text = `${response.description} - ${response.version.name} - ${response.players} online`;
+ document.getElementById("server").appendChild(elem);
+ })
+ })
+ }
+
+ for (let i = 0; i < servers.length; i++) {
+ load_server(servers[i]);
+ }
+
+ let query = new URLSearchParams(window.location.search);
+
+ if (query.has("token") && query.has("user")) {
+ window.localStorage.setItem("token", query.get("token"));
+ window.localStorage.setItem("user", query.get("user"));
+ }
+
+ if (window.localStorage.getItem("token") !== null && window.localStorage.getItem("user") !== null) {
+ document.getElementById("logout").style.setProperty("display", "block");
+ document.getElementById("logout").addEventListener("click", () => {
+ window.localStorage.clear();
+ window.location.reload();
+ })
+ document.getElementById("loginstatus").innerText = `Logged in! (you are ${window.localStorage.getItem("user")})`;
+ }
+
+ document.getElementById("login").href = `${api_server}/select-realm`;
+ </script>
+ </body>
+
+ <style>
+ .joingamebox {
+ width: min-content;
+ padding: 10px;
+ }
+
+ .m-5px {
+ margin: 5px;
+ }
+
+ .w-full {
+ width: 100%;
+ }
+
+ .w-90 {
+ width: 90%;
+ }
+
+ </style>
</html>
M client/package.json => client/package.json +2 -1
@@ 14,5 14,6 @@
"typescript": "^4.9.3",
"vite": "^4.2.0"
},
- "dependencies": {}
+ "dependencies": {},
+ "entry": ["index.html", "play.html"]
}
M client/play.html => client/play.html +28 -1
@@ 4,7 4,6 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>StarKingdoms</title>
- <link rel="stylesheet" href="./static/play.css" />
</head>
<body>
<script type="module" src="/src/index.ts"></script>
@@ 18,4 17,32 @@
<button style="display: none;" id="beamout">Beam out!</button>
</div>
</body>
+
+ <style>
+ :root {
+ --ui-bg-color: gray;
+ --ui-padding: 5px;
+ }
+
+
+ .renderbox {
+ position: absolute;
+ top: 0;
+ left: 0;
+ }
+
+ body {
+ margin: 0;
+ padding: 0;
+ }
+
+ .infobox {
+ position: absolute;
+ bottom: 0;
+ left: calc(50vw - 25%);
+ width: 50%;
+ background-color: var(--ui-bg-color);
+ padding: var(--ui-padding);
+ }
+ </style>
</html>
M client/src/gateway.ts => client/src/gateway.ts +3 -1
@@ 31,11 31,13 @@ export interface GatewayClient {
socket: WebSocket;
username: string | null;
version: number | null;
+ // @ts-ignore
ping_timeout: Timeout | null; // i am aware that these types dont exist
+ // @ts-ignore
ping_timeout_left: Timeout; // its fine
}
-export async function gateway_connect(gateway_url: string, username: string): GatewayClient {
+export async function gateway_connect(gateway_url: string, username: string): Promise<GatewayClient> {
logger.info("FAST CONNECT - Connecting to gateway socket at " + gateway_url);
let ws = await _websocket_connect(gateway_url);
M client/src/index.ts => client/src/index.ts +4 -8
@@ 151,11 151,7 @@ async function client_main(server: string, username: string, texture_quality: st
global.client?.socket.send(encode(MessageC2SInput_packetInfo.type, msg));
}
- let last_time = performance.now();
- let render = (now_time: DOMHighResTimeStamp) => {
- const delta_ms = now_time - last_time;
- last_time = now_time;
-
+ let render = () => {
let viewer_size_x = global.canvas.width;
let viewer_size_y = global.canvas.height;
@@ 169,9 165,9 @@ async function client_main(server: string, username: string, texture_quality: st
global.context.translate(viewer_size_x / 2, viewer_size_y / 2);
if (global.me !== null) {
- document.getElementById("pos").innerText = `Position: ${Math.trunc(global.me.x)}, ${Math.trunc(global.me.y)}`;
+ document.getElementById("pos")!.innerText = `Position: ${Math.trunc(global.me.x)}, ${Math.trunc(global.me.y)}`;
}
- document.getElementById("vel").innerText = `Velocity: ${Math.trunc(global.velocity)}`;
+ document.getElementById("vel")!.innerText = `Velocity: ${Math.trunc(global.velocity)}`;
for (let i = 0; i < global.planets.length; i++) {
let planet = global.planets[i];
@@ 196,7 192,7 @@ async function client_main(server: string, username: string, texture_quality: st
global.context.lineTo(planet.x - global.me!.x, planet.y - global.me!.y);
global.context.stroke();
- document.getElementById("pos-moon").innerText = `Relative to Moon: ${Math.trunc(global.me!.x - planet.x)}, ${Math.trunc(global.me!.y - planet.y)}`
+ document.getElementById("pos-moon")!.innerText = `Relative to Moon: ${Math.trunc(global.me!.x - planet.x)}, ${Math.trunc(global.me!.y - planet.y)}`
}
} else if (planet.planetType == PlanetType.Earth) {
if (global.me !== null) {
M client/src/protocol/message_c2s.ts => client/src/protocol/message_c2s.ts +2 -1
@@ 1,4 1,5 @@
-/* eslint-disable */
+// @ts-nocheck
+
import * as _m0 from "protobufjs/minimal";
import { GoodbyeReason, goodbyeReasonFromJSON, goodbyeReasonToJSON } from "./goodbye_reason";
import { State, stateFromJSON, stateToJSON } from "./state";
M client/src/protocol/starkingdoms-protocol.ts => client/src/protocol/starkingdoms-protocol.ts +1 -1
@@ 1,4 1,4 @@
-/* eslint-disable */
+// @ts-nocheck
import * as Long from "long";
import * as _m0 from "protobufjs/minimal";
D client/static/index.css => client/static/index.css +0 -16
@@ 1,16 0,0 @@
-.joingamebox {
- width: min-content;
- padding: 10px;
-}
-
-.m-5px {
- margin: 5px;
-}
-
-.w-full {
- width: 100%;
-}
-
-.w-90 {
- width: 90%;
-}
D client/static/play.css => client/static/play.css +0 -21
@@ 1,21 0,0 @@
-@import "root.css";
-
-.renderbox {
- position: absolute;
- top: 0;
- left: 0;
-}
-
-body {
- margin: 0;
- padding: 0;
-}
-
-.infobox {
- position: absolute;
- bottom: 0;
- left: calc(50vw - 25%);
- width: 50%;
- background-color: var(--ui-bg-color);
- padding: var(--ui-padding);
-}>
\ No newline at end of file
D client/static/root.css => client/static/root.css +0 -4
@@ 1,4 0,0 @@
-:root {
- --ui-bg-color: gray;
- --ui-padding: 5px;
-}>
\ No newline at end of file
A client/vite.config.ts => client/vite.config.ts +12 -0
@@ 0,0 1,12 @@
+import { defineConfig } from "vite";
+
+export default defineConfig({
+ build: {
+ lib: {
+ entry: {
+ play: "play.html",
+ index: "index.html",
+ }
+ },
+ },
+});
M docker/docker-compose.jinja.yml => docker/docker-compose.jinja.yml +4 -0
@@ 19,6 19,10 @@ services:
- {{ api_port }}:8080
volumes:
- {{ api_config_dir }}:/etc/starkingdoms
+ web:
+ image: registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:web-{{ version }}
+ ports:
+ - {{ web_port }}:80
postgres:
# docker run --name basic-postgres --rm -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=4y7sV96vA9wv46VR -e PGDATA=/var/lib/postgresql/data/pgdata -v /tmp:/var/lib/postgresql/data -p 5432:5432 -it postgres:14.1-alpine
image: postgres:14.1-alpine
A docker/mime-types.conf => docker/mime-types.conf +4 -0
@@ 0,0 1,4 @@
+include mime.types;
+types {
+ application/javascript js mjs cjs;
+}<
\ No newline at end of file
M spacetime => spacetime +58 -44
@@ 40,10 40,12 @@ sub_help() {
echo " clean - Remove all generated files" # done
echo " build_docker_api - Build the API dockerfile" # done
echo " build_docker_server - Build the server dockerfile" # done
- echo " build_docker - Build the API and server containers" # done
+ echo " build_docker_web - Build the web dockerfile" # done
+ echo " build_docker - Build the API, web and server containers" # done
echo " build_docker_api_stable - Build the API container and push it as api-stable" # done
echo " build_docker_server_stable - Build the server container and push it as server-stable" # done
- echo " build_docker_stable - Build the stable api and server containers" # done
+ echo " build_docker_web_stable - Build the web dockerfile and push it as web-stable" # done
+ echo " build_docker_stable - Build the stable api, web and server containers" # done
}
check_install_cargo() {
@@ 70,48 72,6 @@ check_all() {
check atlasify
}
-sub_build_docker_api() {
- cargo build --release --bin starkingdoms-api
- docker buildx build -f api.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-$(git rev-parse --short HEAD) .
- docker buildx build -f api.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-bleeding .
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-$(git rev-parse --short HEAD)
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-bleeding
-}
-
-sub_build_docker_server() {
- cargo build --release --bin starkingdoms-server
- docker buildx build -f server.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-$(git rev-parse --short HEAD) .
- docker buildx build -f server.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-bleeding .
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-$(git rev-parse --short HEAD)
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-bleeding
-}
-
-sub_build_docker_api_stable() {
- cargo build --release --bin starkingdoms-api
- docker buildx build -f api.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-$(git rev-parse --short HEAD) .
- docker buildx build -f api.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-stable .
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-$(git rev-parse --short HEAD)
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:api-stable
-}
-
-sub_build_docker_server_stable() {
- cargo build --release --bin starkingdoms-server
- docker buildx build -f server.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-$(git rev-parse --short HEAD) .
- docker buildx build -f server.Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-stable .
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-$(git rev-parse --short HEAD)
- docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:server-stable
-}
-
-sub_build_docker() {
- sub_build_docker_api
- sub_build_docker_server
-}
-
-sub_build_docker_stable() {
- sub_build_docker_api_stable
- sub_build_docker_server_stable
-}
-
sub_clean() {
rm -rf web/dist
rm -rf assets/dist
@@ 206,6 166,60 @@ sub_build_assets_125() {
exec_ninja asset-125
}
+
+build_docker() {
+ docker buildx build -f "$SCRIPT_DIR/$1".Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:"$1"-$(git rev-parse --short HEAD) "$SCRIPT_DIR"
+ docker buildx build -f "$SCRIPT_DIR/$1".Dockerfile -t registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:"$1"-"$2" "$SCRIPT_DIR"
+ docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:"$1"-$(git rev-parse --short HEAD)
+ docker push registry.gitlab.com/starkingdoms.tk/starkingdoms.tk:"$1"-"$2"
+
+}
+
+sub_build_docker_api() {
+ sub_build_api_prod
+ build_docker "api" "bleeding"
+}
+
+sub_build_docker_server() {
+ sub_build_server_prod
+ build_docker "server" "bleeding"
+}
+
+swap_out_server_for() {
+ echo "[*] Swapping out API server"
+ sed -i'orig' "s/let api_server = \"http:\\/\\/localhost:8080\";/let api_server = \"https:\\/\\/api.$1.$2\";/" "$SCRIPT_DIR/client/index.html"
+ echo "[*] Swapping out game server"
+ sed -i "s/let servers = [\"localhost:3000\"];/let servers = [\"https:\\/\\/$1.$2\"];/" "$SCRIPT_DIR/client/index.html"
+}
+
+sub_build_docker_web() {
+ swap_out_server_for "bleeding" "starkingdoms.io"
+ build_docker "web" "bleeding"
+ mv "$SCRIPT_DIR/client/index.htmlorig" "$SCRIPT_DIR/client/index.html"
+}
+
+sub_build_docker_api_stable() {
+ sub_build_api_prod
+ build_docker "api" "stable"
+}
+
+sub_build_docker_server_stable() {
+ sub_build_server_prod
+ build_docker "server" "stable"
+}
+
+sub_build_docker() {
+ sub_build_docker_api
+ sub_build_docker_server
+ sub_build_docker_web
+}
+
+sub_build_docker_stable() {
+ sub_build_docker_api_stable
+ sub_build_docker_server_stable
+ sub_build_docker_web_stable
+}
+
subcommand=$1
case $subcommand in
"" | "-h" | "--help" | "help")
A web.Dockerfile => web.Dockerfile +14 -0
@@ 0,0 1,14 @@
+FROM node
+
+RUN npm i -g parcel
+
+COPY client /client
+
+RUN cd /client && yarn
+RUN cd /client && yarn build
+
+FROM nginx
+
+COPY --from=0 /client/dist /usr/share/nginx/html
+COPY assets/dist /usr/share/nginx/html
+COPY docker/mime-types.conf /etc/nginx/conf.d/mime-types.conf<
\ No newline at end of file