81 lines
2.8 KiB
TypeScript
81 lines
2.8 KiB
TypeScript
// messages sent between the client and the server, as json over a websocket
|
|
import type { Faces } from "./constants.ts";
|
|
import type { ItemData } from "./inventory.ts";
|
|
|
|
export const AIR_ID = "bworld:air";
|
|
|
|
export interface PlayerInfo {
|
|
id: string;
|
|
name: string;
|
|
x: number;
|
|
y: number;
|
|
z: number;
|
|
yaw: number;
|
|
pitch: number;
|
|
}
|
|
|
|
// x, y, z, block id
|
|
export type BlockChange = [number, number, number, string];
|
|
|
|
// the containers a client can see and click. "screen" is whatever the open server screen shows
|
|
export type ContainerKey = "inventory" | "crafting" | "screen";
|
|
|
|
export const CRAFTING_RESULT_SLOT = 9;
|
|
|
|
// a screen the server opens, drawn below the player's inventory and hotbar
|
|
export interface ScreenLayout {
|
|
// height of the screen's own area, in slots
|
|
rows: number;
|
|
// x and y in slots, can be fractional
|
|
// output slots can only be taken from, like the furnace result
|
|
slots: { index: number; x: number; y: number; output?: boolean }[];
|
|
// progress bars filled from properties[value] / properties[max]
|
|
bars: {
|
|
x: number;
|
|
y: number;
|
|
value: string;
|
|
max: string;
|
|
direction: "up" | "right";
|
|
empty_texture: string;
|
|
full_texture: string;
|
|
}[];
|
|
}
|
|
|
|
// clients send what the player is trying to do, the server decides what happens
|
|
export type ClientMessage =
|
|
| { type: "hello"; name: string }
|
|
| { type: "move"; x: number; y: number; z: number; yaw: number; pitch: number }
|
|
| { type: "break_block"; x: number; y: number; z: number }
|
|
// right click on a block: interact with it, or place the held block against `face`
|
|
| { type: "use_block"; x: number; y: number; z: number; face: Faces }
|
|
| { type: "select_slot"; slot: number }
|
|
| { type: "click"; container: ContainerKey; index: number; button: number }
|
|
// closes the open screen, including the player's own inventory screen
|
|
| { type: "close_screen" }
|
|
| { type: "chat"; text: string };
|
|
|
|
export type ServerMessage =
|
|
| {
|
|
type: "welcome";
|
|
id: string;
|
|
seed: string;
|
|
players: PlayerInfo[];
|
|
changes: BlockChange[];
|
|
spawn: { x: number; y: number; z: number; yaw: number; pitch: number };
|
|
selected_slot: number;
|
|
}
|
|
| { type: "player_join"; player: PlayerInfo }
|
|
| { type: "player_leave"; id: string }
|
|
| { type: "player_move"; id: string; x: number; y: number; z: number; yaw: number; pitch: number }
|
|
// also sent to the player who caused it, which corrects anything their client predicted wrong
|
|
| { type: "set_block"; x: number; y: number; z: number; id: string }
|
|
| { type: "chat"; from?: string; text: string }
|
|
| { type: "container"; container: ContainerKey; items: (ItemData | null)[] }
|
|
| { type: "cursor"; item: ItemData | null }
|
|
| { type: "open_screen"; layout: ScreenLayout; properties: Record<string, number> }
|
|
| { type: "screen_properties"; properties: Record<string, number> }
|
|
| { type: "close_screen" };
|
|
|
|
export const MAX_NAME_LENGTH = 16;
|
|
export const MAX_CHAT_LENGTH = 256;
|