Server authority
This commit is contained in:
@@ -2,6 +2,10 @@ import { System } from "$/common/ecs/mod.ts";
|
||||
import { Position } from "$/common/components/position.ts";
|
||||
import { ClientWorld } from "../client_world.ts";
|
||||
import { Camera } from "../components/camera.ts";
|
||||
import { Container, ItemStack } from "$/common/inventory.ts";
|
||||
import { PlayerComponent } from "../player.ts";
|
||||
import { GuiContainer } from "../gui/gui_container.ts";
|
||||
import { show_fatal_error } from "../fatal.ts";
|
||||
|
||||
const MOVE_SEND_INTERVAL = 1 / 10;
|
||||
const REMOTE_PLAYER_SMOOTHING = 12;
|
||||
@@ -11,9 +15,9 @@ export class NetworkSystem extends System {
|
||||
|
||||
update(world: ClientWorld, delta: number): void {
|
||||
const connection = world.connection;
|
||||
if (!connection) {
|
||||
return;
|
||||
}
|
||||
const [local_player] = world.get_tag("player")!;
|
||||
const player_component = local_player.get(PlayerComponent)!;
|
||||
const inventories = player_component.inventories;
|
||||
|
||||
for (const message of connection.incoming) {
|
||||
switch (message.type) {
|
||||
@@ -41,13 +45,47 @@ export class NetworkSystem extends System {
|
||||
case "chat":
|
||||
world.add_chat(message.from ? `<${message.from}> ${message.text}` : message.text);
|
||||
break;
|
||||
case "container": {
|
||||
let container = message.container === "screen"
|
||||
? inventories.screen
|
||||
: inventories[message.container];
|
||||
if (message.container === "screen" && container?.size !== message.items.length) {
|
||||
container = inventories.screen = new Container(message.items.length);
|
||||
}
|
||||
container?.load(message.items);
|
||||
break;
|
||||
}
|
||||
case "cursor":
|
||||
inventories.cursor.item = message.item ? ItemStack.from_data(message.item) : undefined;
|
||||
break;
|
||||
case "open_screen": {
|
||||
// replace anything open locally without telling the server, it just opened this one
|
||||
player_component.screens.length = 0;
|
||||
const size = Math.max(0, ...message.layout.slots.map((slot) => slot.index + 1));
|
||||
inventories.screen = new Container(size);
|
||||
player_component.screens.push(
|
||||
new GuiContainer(inventories, (m) => connection.send(m), message.layout, message.properties),
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "screen_properties": {
|
||||
const screen = player_component.screens.at(-1);
|
||||
if (screen instanceof GuiContainer) {
|
||||
screen.properties = message.properties;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "close_screen":
|
||||
// closed by the server (the block broke), it already put everything back
|
||||
player_component.screens = player_component.screens.filter((s) => !(s instanceof GuiContainer));
|
||||
inventories.screen = undefined;
|
||||
break;
|
||||
}
|
||||
}
|
||||
connection.incoming.length = 0;
|
||||
|
||||
if (connection.closed) {
|
||||
world.add_chat("Lost connection to the server");
|
||||
world.connection = undefined;
|
||||
show_fatal_error("Lost connection to the server");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user