runic-server/server.js

212 lines
6.9 KiB
JavaScript
Raw Normal View History

2023-03-03 12:25:41 -08:00
const WebSocket = require("ws");
const Engine = require("./engine");
const { StringDecoder } = require("string_decoder");
const decoder = new StringDecoder('utf8');
var game_data = {
"character": {
"variants": [
"green"
],
"radius": 40
},
"world": {
"biome": {
"forest": {
"ground": {},
"tree": {
"radius": 50,
"size": 180
},
"boulder": {
"radius": 60,
"size": 130
}
}
}
}
}
var nodes = new Set();
var characters = new Set();
var server_fps = 20;
var player_render_distance = 1000;
var port = 8080;
var max_player_speed = 500;
function message(type, data, from) {
if (type === "movement") {
2023-03-03 12:25:41 -08:00
if ("position" in data) {
try {
let new_position = new Engine.vector(data.position.x, data.position.y);
if (from.position.distance_to(new_position) <= max_player_speed / server_fps) {
from.position.x = new_position.x;
from.position.y = new_position.y;
}
else {
var to_send = {
"type": "position_update",
"data": {
"position": {
"x": from.position.x,
"y": from.position.y
}
}
}
from.socket.send(JSON.stringify(to_send));
}
}
catch(err) {
console.log(from.username + ": Bad position packet!");
console.log(err);
}
}
if ("rotation" in data) {
from.rotation = data.rotation;
}
}
else if (type === "interact") {
//calculate circle of influence position
let circle_position = new Engine.vector(0, 30);
circle_position.rotate(from.rotation);
circle_position.add(from.position);
//console.log(circle_position);
influence_circle = {
"position": circle_position,
"radius": 50
}
nodes.forEach(function(itr, idx) {
if (influence_circle.position.distance_to(itr.position) <= influence_circle.radius+itr.radius) {
//console.log(from.username+" just hit a "+itr.type);
}
});
}
2023-03-03 12:25:41 -08:00
else {
console.log(from.username + ": Bad packet!");
console.log(type);
console.dir(data);
}
}
var server = new WebSocket.Server({
port: port
});
console.log("Server has started on port " + port);
server.on("connection", function (socket, request) {
socket.on("message", function(msg) {
let boffer = Buffer.from(msg);
let data = JSON.parse(decoder.write(boffer));
if (data.type === "init") { //character joins
let this_username = "Anonymous";
let this_variant = 0;
if ("username" in data.data) {
this_username = data.data.username;
2023-03-03 12:25:41 -08:00
}
if ("variant" in data.data) {
if (data.data.variant >= 0 < game_data.character.variants.length) {
this_variant = Math.round(data.data.variant);
}
}
let this_player = new Engine.character(new Engine.vector(0, 0), 0, 0, this_username, socket);
this_player.id = Engine.create_id();
characters.add(this_player);
socket.send(JSON.stringify({"type": "server_data", "data": {"fps": server_fps}}));
socket.send(JSON.stringify({"type": "world", "data": Array.from(nodes)}));
console.log(this_username + " joined the game");
socket.on("message", function(msg) {
let boffer = Buffer.from(msg);
let data = JSON.parse(decoder.write(boffer));
message(data.type, data.data, this_player);
});
socket.on("close", function() {
let char_array = Array.from(characters);
for (let itr in char_array) {
let this_character = char_array[itr];
if (this_character.id === this_player.id) {
socket.close();
characters.delete(this_character);
}
}
console.log(this_player.username + " has disconnected");
});
2023-03-03 12:25:41 -08:00
}
});
2023-03-03 12:25:41 -08:00
});
function do_collisions() {
characters.forEach(function(this_character) {
nodes.forEach(function(this_node) {
Engine.collide(this_node, this_character);
});
});
}
2023-03-03 12:25:41 -08:00
function server_tick() {
do_collisions();
2023-03-03 12:25:41 -08:00
var char_array = Array.from(characters);
//send other players
for (let this_player_num in char_array) {
let this_player = char_array[this_player_num];
let other_players = new Array();
for (let testing_player_num in char_array) {
let testing_player = char_array[testing_player_num];
if (this_player.id != testing_player.id) {
if (this_player.position.distance_to(testing_player.position) <= player_render_distance) {
other_players.push({
"username": testing_player.username,
"position": testing_player.position,
"rotation": testing_player.rotation,
"health": testing_player.health,
"variant": testing_player.variant,
"id": testing_player.id
});
}
}
}
this_player.socket.send(JSON.stringify({"type": "other_players", "data": other_players}));
}
}
2023-03-03 14:33:13 -08:00
setInterval(server_tick, 1000 / server_fps);
function random_rot() {
let rot = Math.floor(Math.random() * 360);
let rot_rad = rot * (Math.PI/180);
return rot_rad;
}
function random_pos() {
return new Engine.vector((Math.random() * 10000)-5000, (Math.random() * 10000)-5000);
}
function create_boulder(position, rotation) {
nodes.add(new Engine.node(position, rotation, game_data.world.biome.forest.boulder.radius, game_data.world.biome.forest.boulder.size, "boulder"));
2023-03-03 14:33:13 -08:00
}
function create_tree(position, rotation) {
nodes.add(new Engine.node(position, rotation, game_data.world.biome.forest.tree.radius, game_data.world.biome.forest.tree.size, "tree"));
2023-03-03 14:33:13 -08:00
}
function generate_world() {
/*for (let i=0; i<100; i++) {
let new_tree_pos = random_pos();
let nodes_arr = Array.from(nodes);
for (test_node_itr in nodes_arr) {
let test_node = nodes_arr[test_node_itr];
//console.dir(test_node);
if (new_tree_pos.distance_to(test_node.position) > 70) {
create_tree(new_tree_pos, random_rot());
}
}
create_boulder(random_pos(), random_rot());
}*/
create_tree(new Engine.vector(50, 50), 2)
create_boulder(new Engine.vector(-50, 50), 2)
2023-03-03 14:33:13 -08:00
}
generate_world();