Skip to content

Commit 01f554f

Browse files
authored
Merge pull request #1 from oracle-devrel/migration
migration from vmleon/oci-multiplayer
2 parents 265d59f + dd5684e commit 01f554f

File tree

422 files changed

+73426
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

422 files changed

+73426
-1
lines changed

.gitignore

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,84 @@ Temporary Items
3030
.key
3131
.crt
3232
.csr
33-
.pem
33+
.pem
34+
35+
node_modules/
36+
build/
37+
dist/
38+
generated/
39+
dump.rdb
40+
41+
**/.terraform/*
42+
*.tfstate
43+
*.tfstate.*
44+
*.tfvars
45+
override.tf
46+
override.tf.json
47+
*_override.tf
48+
*_override.tf.json
49+
.terraform.lock.hcl
50+
.terraformrc
51+
terraform.rc
52+
53+
*.log
54+
logs
55+
*.lock
56+
57+
*.retry
58+
59+
*.pem
60+
*.key
61+
*.crt
62+
*.conf
63+
64+
appendonlydir/
65+
66+
.env_server
67+
.env
68+
.env.json
69+
70+
HELP.md
71+
.gradle
72+
build/
73+
!gradle/wrapper/gradle-wrapper.jar
74+
!**/src/main/**/build/
75+
!**/src/test/**/build/
76+
build.gradle-e
77+
78+
wallet.zip
79+
deploy/**/application.properties
80+
deploy/k8s/overlays/prod/kustomization.yaml
81+
82+
### STS ###
83+
.apt_generated
84+
.classpath
85+
.factorypath
86+
.project
87+
.settings
88+
.springBeans
89+
.sts4-cache
90+
bin/
91+
!**/src/main/**/bin/
92+
!**/src/test/**/bin/
93+
94+
### IntelliJ IDEA ###
95+
.idea
96+
*.iws
97+
*.iml
98+
*.ipr
99+
out/
100+
!**/src/main/**/out/
101+
!**/src/test/**/out/
102+
103+
### NetBeans ###
104+
/nbproject/private/
105+
/nbbuild/
106+
/dist/
107+
/nbdist/
108+
/.nb-gradle/
109+
110+
### VS Code ###
111+
.vscode/
112+
*.dtmp
113+
*.bkp

bots/.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
node_modules
2+
npm-debug.log
3+
Dockerfile
4+
config

bots/Dockerfile

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM --platform=linux/amd64 node:20-slim
2+
3+
WORKDIR /usr/src/app
4+
5+
COPY package*.json ./
6+
7+
RUN npm install
8+
# RUN npm ci --only=production
9+
10+
COPY . .
11+
12+
CMD [ "node", "index.js" ]

bots/index.js

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
import { io } from "socket.io-client";
2+
import * as dotenv from "dotenv";
3+
import short from "shortid";
4+
import pino from "pino";
5+
import * as THREE from "three";
6+
import { throttle } from "throttle-debounce";
7+
8+
dotenv.config({ path: "./config/.env" });
9+
const logger = pino();
10+
11+
const NODE_ENV = process.env.NODE_ENV || "development";
12+
logger.info(`NODE_ENV: ${NODE_ENV}`);
13+
14+
const TRACE_RATE_IN_MILLIS = parseInt(process.env.TRACE_RATE_IN_MILLIS) || 10;
15+
logger.info(`TRACE_RATE_IN_MILLIS: ${TRACE_RATE_IN_MILLIS} ms`);
16+
17+
const yourId = short();
18+
const yourName = `Bot ${yourId}`;
19+
logger.info(`Name: ${yourName}`);
20+
21+
const BOUNDARY_WIDTH = parseInt(process.env.BOUNDARY_WIDTH) || 89;
22+
const BOUNDARY_HEIGHT = parseInt(process.env.BOUNDARY_HEIGHT) || 23;
23+
const boundaries = { width: BOUNDARY_WIDTH, height: BOUNDARY_HEIGHT };
24+
logger.info(`Boundaries: ${JSON.stringify(boundaries)}`);
25+
26+
const WS_SERVER_SERVICE_HOST = process.env.WS_SERVER_SERVICE_HOST;
27+
if (!WS_SERVER_SERVICE_HOST) {
28+
logger.error(`WS_SERVER_SERVICE_HOST not defined`);
29+
process.exit(1);
30+
}
31+
const WS_SERVER_SERVICE_PORT = process.env.WS_SERVER_SERVICE_PORT;
32+
if (!WS_SERVER_SERVICE_PORT) {
33+
logger.error(`WS_SERVER_SERVICE_PORT not defined`);
34+
process.exit(1);
35+
}
36+
37+
let items = {};
38+
let players = {};
39+
40+
const logTrace = throttle(1000, (message) => logger.info(message));
41+
42+
const webSocketServerUrl = `ws://${WS_SERVER_SERVICE_HOST}:${WS_SERVER_SERVICE_PORT}`;
43+
logger.info(`Connecting to WS Server on ${webSocketServerUrl}`);
44+
const socket = io(webSocketServerUrl);
45+
46+
socket.on("server.info", (data) => {
47+
logger.info(`Server Info: ${JSON.stringify(data)}`);
48+
});
49+
50+
socket.on("items.all", (data) => {
51+
// FIXME measure lag
52+
const itemIdToDestroy = data;
53+
delete items[itemIdToDestroy];
54+
});
55+
56+
socket.on("item.new", (data) => {
57+
// FIXME measure lag
58+
items = data;
59+
});
60+
61+
socket.on("item.destroy", (data) => {
62+
// FIXME measure lag
63+
items = data;
64+
});
65+
66+
socket.on("player.trace.all", (data) => {
67+
// FIXME measure lag
68+
for (const [key, traceData] of Object.entries(data)) {
69+
players[key] = players[key] ? { ...players[key], ...traceData } : traceData;
70+
}
71+
});
72+
73+
socket.on("player.info.joined", (data) => {
74+
// FIXME measure lag
75+
const { id: joinedId, name: joinedName } = data;
76+
players[joinedId] = players[joinedId]
77+
? { ...players[joinedId], name: joinedName }
78+
: { name: joinedName };
79+
});
80+
81+
socket.on("player.info.left", (data) => {
82+
// FIXME measure lag
83+
const playerId = data;
84+
delete players[playerId];
85+
});
86+
87+
socket.on("connect", () => {
88+
logger.info(`Connected to ${webSocketServerUrl}`);
89+
});
90+
91+
socket.on("disconnect", () => {
92+
logger.info(`Disconnected from ${webSocketServerUrl}`);
93+
});
94+
95+
socket.on("error", (error) => {
96+
logger.error(error);
97+
});
98+
99+
socket.emit("player.info.joining", { id: yourId, name: yourName });
100+
101+
const ACCELERATION = 0.005;
102+
const BRAKE = 0.1;
103+
const MAX_SPEED = 0.05;
104+
const TURN_SPEED = Math.PI / 180;
105+
106+
const player = new THREE.Mesh();
107+
let playerSpeed = 0;
108+
109+
let keyboard = {
110+
ArrowUp: false,
111+
ArrowDown: false,
112+
ArrowLeft: false,
113+
ArrowRight: false,
114+
};
115+
116+
setInterval(() => {
117+
animateBot();
118+
const { x, y } = player.position;
119+
const { z: rotZ } = player.rotation;
120+
const trace = {
121+
id: yourId,
122+
x: x.toFixed(5),
123+
y: y.toFixed(5),
124+
rotZ: rotZ.toFixed(5), // add rotation Z value
125+
};
126+
logTrace(`Trace: ${JSON.stringify(trace)}`);
127+
socket.emit("player.trace.change", trace);
128+
}, TRACE_RATE_IN_MILLIS);
129+
130+
setInterval(() => {
131+
keyboard["ArrowUp"] = true;
132+
setTimeout(() => {
133+
keyboard["ArrowUp"] = false;
134+
}, 300);
135+
}, 3 * 1000);
136+
137+
setInterval(() => {
138+
keyboard["ArrowLeft"] = true;
139+
setTimeout(() => {
140+
keyboard["ArrowLeft"] = false;
141+
}, 300);
142+
}, 3 * 1000);
143+
144+
function animateBot() {
145+
let movement = new THREE.Vector3(0, 0, 0);
146+
147+
if (keyboard["ArrowUp"]) {
148+
playerSpeed += ACCELERATION;
149+
} else if (keyboard["ArrowDown"]) {
150+
playerSpeed -= BRAKE;
151+
} else {
152+
playerSpeed *= 0.98; // Decelerate if no acceleration or braking input
153+
}
154+
155+
playerSpeed = Math.max(Math.min(playerSpeed, MAX_SPEED), -MAX_SPEED);
156+
157+
if (keyboard["ArrowLeft"]) {
158+
player.rotation.z += TURN_SPEED;
159+
}
160+
if (keyboard["ArrowRight"]) {
161+
player.rotation.z -= TURN_SPEED;
162+
}
163+
164+
const direction = new THREE.Vector3(0, 1, 0).applyQuaternion(
165+
player.quaternion
166+
);
167+
168+
movement.copy(direction).multiplyScalar(playerSpeed);
169+
170+
player.position.add(movement);
171+
}
172+
173+
async function terminate() {
174+
await socket.close();
175+
process.exit(0);
176+
}
177+
178+
process.on("SIGTERM", async () => {
179+
await terminate();
180+
});
181+
182+
process.on("SIGINT", async () => {
183+
await terminate();
184+
});

0 commit comments

Comments
 (0)