Merge remote-tracking branch 'origin/master' into add-github-actions

This commit is contained in:
SpiralP 2021-11-14 00:02:13 -08:00
commit ee9ce314a5
6 changed files with 100 additions and 49 deletions

View File

@ -1,4 +1,6 @@
The website will be structured like so: The page provides a complete example for how to integrate the webclient into a simple website
The example website will be structured like so:
``` ```
websrv.py websrv.py

View File

@ -73,7 +73,7 @@ You are required to have this HTML code somewhere in the page:
### Complete example ### Complete example
The links below show implementing a simple website that hosts the web client The links below show how to integrate the webclient into a simple website
* [Flask (python webserver)](hosting-flask.md) * [Flask (python webserver)](hosting-flask.md)
### iOS / Android support ### iOS / Android support

View File

@ -335,6 +335,7 @@ static void Commands_Execute(const cc_string* input) {
struct ChatCommand* cmd; struct ChatCommand* cmd;
int offset, count; int offset, count;
cc_string name, value;
cc_string args[50]; cc_string args[50];
if (String_CaselessStarts(&text, &prefixSpace)) { /* /client command args */ if (String_CaselessStarts(&text, &prefixSpace)) { /* /client command args */
@ -349,15 +350,22 @@ static void Commands_Execute(const cc_string* input) {
/* Check for only / or /client */ /* Check for only / or /client */
if (!text.length) { Commands_PrintDefault(); return; } if (!text.length) { Commands_PrintDefault(); return; }
count = String_UNSAFE_Split(&text, ' ', args, Array_Elems(args)); String_UNSAFE_Separate(&text, ' ', &name, &value);
cmd = Commands_FindMatch(&args[0]); cmd = Commands_FindMatch(&name);
if (!cmd) return; if (!cmd) return;
if (cmd->singleplayerOnly && !Server.IsSinglePlayer) { if ((cmd->flags & COMMAND_FLAG_SINGLEPLAYER_ONLY) && !Server.IsSinglePlayer) {
Chat_Add1("&e/client: \"&f%s&e\" can only be used in singleplayer.", &args[0]); Chat_Add1("&e/client: \"&f%s&e\" can only be used in singleplayer.", &name);
return; return;
} }
cmd->Execute(&args[1], count - 1);
if (cmd->flags & COMMAND_FLAG_UNSPLIT_ARGS) {
/* argsCount = 0 if value.length is 0, 1 otherwise */
cmd->Execute(&value, value.length != 0);
} else {
count = String_UNSAFE_Split(&value, ' ', args, Array_Elems(args));
cmd->Execute(args, count);
}
} }
@ -369,7 +377,7 @@ static void HelpCommand_Execute(const cc_string* args, int argsCount) {
int i; int i;
if (!argsCount) { Commands_PrintDefault(); return; } if (!argsCount) { Commands_PrintDefault(); return; }
cmd = Commands_FindMatch(&args[0]); cmd = Commands_FindMatch(args);
if (!cmd) return; if (!cmd) return;
for (i = 0; i < Array_Elems(cmd->help); i++) { for (i = 0; i < Array_Elems(cmd->help); i++) {
@ -379,7 +387,8 @@ static void HelpCommand_Execute(const cc_string* args, int argsCount) {
} }
static struct ChatCommand HelpCommand = { static struct ChatCommand HelpCommand = {
"Help", HelpCommand_Execute, false, "Help", HelpCommand_Execute,
COMMAND_FLAG_UNSPLIT_ARGS,
{ {
"&a/client help [command name]", "&a/client help [command name]",
"&eDisplays the help for the given command.", "&eDisplays the help for the given command.",
@ -399,7 +408,8 @@ static void GpuInfoCommand_Execute(const cc_string* args, int argsCount) {
} }
static struct ChatCommand GpuInfoCommand = { static struct ChatCommand GpuInfoCommand = {
"GpuInfo", GpuInfoCommand_Execute, false, "GpuInfo", GpuInfoCommand_Execute,
COMMAND_FLAG_UNSPLIT_ARGS,
{ {
"&a/client gpuinfo", "&a/client gpuinfo",
"&eDisplays information about your GPU.", "&eDisplays information about your GPU.",
@ -412,18 +422,19 @@ static void RenderTypeCommand_Execute(const cc_string* args, int argsCount) {
Chat_AddRaw("&e/client: &cYou didn't specify a new render type."); return; Chat_AddRaw("&e/client: &cYou didn't specify a new render type."); return;
} }
flags = EnvRenderer_CalcFlags(&args[0]); flags = EnvRenderer_CalcFlags(args);
if (flags >= 0) { if (flags >= 0) {
EnvRenderer_SetMode(flags); EnvRenderer_SetMode(flags);
Options_Set(OPT_RENDER_TYPE, &args[0]); Options_Set(OPT_RENDER_TYPE, args);
Chat_Add1("&e/client: &fRender type is now %s.", &args[0]); Chat_Add1("&e/client: &fRender type is now %s.", args);
} else { } else {
Chat_Add1("&e/client: &cUnrecognised render type &f\"%s\"&c.", &args[0]); Chat_Add1("&e/client: &cUnrecognised render type &f\"%s\"&c.", args);
} }
} }
static struct ChatCommand RenderTypeCommand = { static struct ChatCommand RenderTypeCommand = {
"RenderType", RenderTypeCommand_Execute, false, "RenderType", RenderTypeCommand_Execute,
COMMAND_FLAG_UNSPLIT_ARGS,
{ {
"&a/client rendertype [normal/legacy/legacyfast]", "&a/client rendertype [normal/legacy/legacyfast]",
"&bnormal: &eDefault renderer, with all environmental effects enabled.", "&bnormal: &eDefault renderer, with all environmental effects enabled.",
@ -451,7 +462,8 @@ static void ResolutionCommand_Execute(const cc_string* args, int argsCount) {
} }
static struct ChatCommand ResolutionCommand = { static struct ChatCommand ResolutionCommand = {
"Resolution", ResolutionCommand_Execute, false, "Resolution", ResolutionCommand_Execute,
0,
{ {
"&a/client resolution [width] [height]", "&a/client resolution [width] [height]",
"&ePrecisely sets the size of the rendered window.", "&ePrecisely sets the size of the rendered window.",
@ -460,14 +472,15 @@ static struct ChatCommand ResolutionCommand = {
static void ModelCommand_Execute(const cc_string* args, int argsCount) { static void ModelCommand_Execute(const cc_string* args, int argsCount) {
if (argsCount) { if (argsCount) {
Entity_SetModel(&LocalPlayer_Instance.Base, &args[0]); Entity_SetModel(&LocalPlayer_Instance.Base, args);
} else { } else {
Chat_AddRaw("&e/client model: &cYou didn't specify a model name."); Chat_AddRaw("&e/client model: &cYou didn't specify a model name.");
} }
} }
static struct ChatCommand ModelCommand = { static struct ChatCommand ModelCommand = {
"Model", ModelCommand_Execute, true, "Model", ModelCommand_Execute,
COMMAND_FLAG_SINGLEPLAYER_ONLY | COMMAND_FLAG_UNSPLIT_ARGS,
{ {
"&a/client model [name]", "&a/client model [name]",
"&bnames: &echibi, chicken, creeper, human, pig, sheep", "&bnames: &echibi, chicken, creeper, human, pig, sheep",
@ -481,7 +494,8 @@ static void ClearDeniedCommand_Execute(const cc_string* args, int argsCount) {
} }
static struct ChatCommand ClearDeniedCommand = { static struct ChatCommand ClearDeniedCommand = {
"ClearDenied", ClearDeniedCommand_Execute, false, "ClearDenied", ClearDeniedCommand_Execute,
COMMAND_FLAG_UNSPLIT_ARGS,
{ {
"&a/client cleardenied", "&a/client cleardenied",
"&eClears the list of texture pack URLs you have denied", "&eClears the list of texture pack URLs you have denied",
@ -496,29 +510,7 @@ static int cuboid_block = -1;
static IVec3 cuboid_mark1, cuboid_mark2; static IVec3 cuboid_mark1, cuboid_mark2;
static cc_bool cuboid_persist, cuboid_hooked, cuboid_hasMark1; static cc_bool cuboid_persist, cuboid_hooked, cuboid_hasMark1;
static const cc_string cuboid_msg = String_FromConst("&eCuboid: &fPlace or delete a block."); static const cc_string cuboid_msg = String_FromConst("&eCuboid: &fPlace or delete a block.");
static const cc_string yes_string = String_FromConst("yes");
static cc_bool CuboidCommand_ParseArgs(const cc_string* args, int argsCount) {
int block;
if (!argsCount) return true;
if (String_CaselessEqualsConst(&args[argsCount - 1], "yes")) {
cuboid_persist = true;
/* special case "/cuboid yes" */
if (argsCount == 1) return true;
}
block = Block_Parse(&args[0]);
if (block == -1) {
Chat_Add1("&eCuboid: &c\"%s\" is not a valid block name or id.", &args[0]); return false;
}
if (block >= BLOCK_CPE_COUNT && !Block_IsCustomDefined(block)) {
Chat_Add1("&eCuboid: &cThere is no block with id \"%s\".", &args[0]); return false;
}
cuboid_block = block;
return true;
}
static void CuboidCommand_DoCuboid(void) { static void CuboidCommand_DoCuboid(void) {
IVec3 min, max; IVec3 min, max;
@ -568,6 +560,33 @@ static void CuboidCommand_BlockChanged(void* obj, IVec3 coords, BlockID old, Blo
} }
} }
static cc_bool CuboidCommand_ParseArgs(const cc_string* args) {
cc_string value = *args;
int block;
/* Check for /cuboid [block] yes */
if (String_CaselessEnds(&value, &yes_string)) {
cuboid_persist = true;
value.length -= 3;
String_UNSAFE_TrimEnd(&value);
/* special case "/cuboid yes" */
if (!value.length) return true;
}
block = Block_Parse(&value);
if (block == -1) {
Chat_Add1("&eCuboid: &c\"%s\" is not a valid block name or id.", &value); return false;
}
if (block >= BLOCK_CPE_COUNT && !Block_IsCustomDefined(block)) {
Chat_Add1("&eCuboid: &cThere is no block with id \"%s\".", &value); return false;
}
cuboid_block = block;
return true;
}
static void CuboidCommand_Execute(const cc_string* args, int argsCount) { static void CuboidCommand_Execute(const cc_string* args, int argsCount) {
if (cuboid_hooked) { if (cuboid_hooked) {
Event_Unregister_(&UserEvents.BlockChanged, NULL, CuboidCommand_BlockChanged); Event_Unregister_(&UserEvents.BlockChanged, NULL, CuboidCommand_BlockChanged);
@ -577,7 +596,7 @@ static void CuboidCommand_Execute(const cc_string* args, int argsCount) {
cuboid_block = -1; cuboid_block = -1;
cuboid_hasMark1 = false; cuboid_hasMark1 = false;
cuboid_persist = false; cuboid_persist = false;
if (!CuboidCommand_ParseArgs(args, argsCount)) return; if (argsCount && !CuboidCommand_ParseArgs(args)) return;
Chat_AddOf(&cuboid_msg, MSG_TYPE_CLIENTSTATUS_1); Chat_AddOf(&cuboid_msg, MSG_TYPE_CLIENTSTATUS_1);
Event_Register_(&UserEvents.BlockChanged, NULL, CuboidCommand_BlockChanged); Event_Register_(&UserEvents.BlockChanged, NULL, CuboidCommand_BlockChanged);
@ -585,7 +604,8 @@ static void CuboidCommand_Execute(const cc_string* args, int argsCount) {
} }
static struct ChatCommand CuboidCommand = { static struct ChatCommand CuboidCommand = {
"Cuboid", CuboidCommand_Execute, true, "Cuboid", CuboidCommand_Execute,
COMMAND_FLAG_SINGLEPLAYER_ONLY | COMMAND_FLAG_UNSPLIT_ARGS,
{ {
"&a/client cuboid [block] [persist]", "&a/client cuboid [block] [persist]",
"&eFills the 3D rectangle between two points with [block].", "&eFills the 3D rectangle between two points with [block].",
@ -618,7 +638,8 @@ static void TeleportCommand_Execute(const cc_string* args, int argsCount) {
} }
static struct ChatCommand TeleportCommand = { static struct ChatCommand TeleportCommand = {
"TP", TeleportCommand_Execute, true, "TP", TeleportCommand_Execute,
COMMAND_FLAG_SINGLEPLAYER_ONLY,
{ {
"&a/client tp [x y z]", "&a/client tp [x y z]",
"&eMoves you to the given coordinates.", "&eMoves you to the given coordinates.",

View File

@ -39,13 +39,18 @@ extern double Chat_AnnouncementReceived;
extern double Chat_BigAnnouncementReceived; extern double Chat_BigAnnouncementReceived;
extern double Chat_SmallAnnouncementReceived; extern double Chat_SmallAnnouncementReceived;
/* This command is only available in singleplayer */
#define COMMAND_FLAG_SINGLEPLAYER_ONLY 0x01
/* args is passed as a single string instead of being split by spaces */
#define COMMAND_FLAG_UNSPLIT_ARGS 0x02
struct ChatCommand; struct ChatCommand;
/* Represents a client-side command/action. */ /* Represents a client-side command/action. */
struct ChatCommand { struct ChatCommand {
const char* name; /* Full name of this command */ const char* name; /* Full name of this command */
/* Function pointer for the actual action the command performs */ /* Function pointer for the actual action the command performs */
void (*Execute)(const cc_string* args, int argsCount); void (*Execute)(const cc_string* args, int argsCount);
cc_bool singleplayerOnly; /* Whether this command is only usable in singleplayer */ cc_uint8 flags; /* Flags for handling this command (see COMMAND_FLAG defines) */
const char* help[5]; /* Messages to show when a player uses /help on this command */ const char* help[5]; /* Messages to show when a player uses /help on this command */
struct ChatCommand* next; /* Next command in linked-list of client commands */ struct ChatCommand* next; /* Next command in linked-list of client commands */
}; };

View File

@ -519,6 +519,11 @@ static void APIENTRY fake_vertexPointer(GLint size, GLenum type, GLsizei stride,
} }
static void OpenGL11Fallback(void) { static void OpenGL11Fallback(void) {
Window_ShowDialog("Performance warning",
"Your system only supports only OpenGL 1.1\n" \
"This is usually caused by graphics drivers not being installed\n\n" \
"As such you will likely experience very poor performance");
_glBindBuffer = fake_bindBuffer; _glDeleteBuffers = fake_deleteBuffers; _glBindBuffer = fake_bindBuffer; _glDeleteBuffers = fake_deleteBuffers;
_glGenBuffers = fake_genBuffers; _glBufferData = fake_bufferData; _glGenBuffers = fake_genBuffers; _glBufferData = fake_bufferData;
_glBufferSubData = fake_bufferSubData; _glBufferSubData = fake_bufferSubData;

View File

@ -13,6 +13,14 @@ ifndef $(PLAT)
else else
PLAT=$(shell uname -s | tr '[:upper:]' '[:lower:]') PLAT=$(shell uname -s | tr '[:upper:]' '[:lower:]')
endif endif
ifeq ($(PLAT),darwin)
ifeq ($(shell uname -m), x86_64)
PLAT=mac_x64
else
PLAT=mac_x32
endif
endif
endif endif
ifeq ($(PLAT),web) ifeq ($(PLAT),web)
@ -40,11 +48,19 @@ CFLAGS=-g -pipe -fno-math-errno
LIBS=-lm -lsocket -lX11 -lXi -lGL LIBS=-lm -lsocket -lX11 -lXi -lGL
endif endif
ifeq ($(PLAT),darwin) ifeq ($(PLAT),mac_x32)
LIBS= LIBS=
CFLAGS=-g -m32 -pipe -fno-math-errno
LDFLAGS=-rdynamic -framework Carbon -framework AGL -framework OpenGL -framework IOKit LDFLAGS=-rdynamic -framework Carbon -framework AGL -framework OpenGL -framework IOKit
endif endif
ifeq ($(PLAT),mac_x64)
SOURCES+=interop_cocoa.m
CFLAGS=-g -m64 -pipe -fno-math-errno
LIBS=
LDFLAGS=-rdynamic -framework Cocoa -framework OpenGL -framework IOKit -lobjc
endif
ifeq ($(PLAT),freebsd) ifeq ($(PLAT),freebsd)
CFLAGS=-g -pipe -I /usr/local/include -fno-math-errno CFLAGS=-g -pipe -I /usr/local/include -fno-math-errno
LDFLAGS=-L /usr/local/lib -rdynamic LDFLAGS=-L /usr/local/lib -rdynamic
@ -89,8 +105,10 @@ mingw:
$(MAKE) $(ENAME) PLAT=mingw -j$(JOBS) $(MAKE) $(ENAME) PLAT=mingw -j$(JOBS)
sunos: sunos:
$(MAKE) $(ENAME) PLAT=sunos -j$(JOBS) $(MAKE) $(ENAME) PLAT=sunos -j$(JOBS)
darwin: mac_x32:
$(MAKE) $(ENAME) PLAT=darwin -j$(JOBS) $(MAKE) $(ENAME) PLAT=mac_x32 -j$(JOBS)
mac_x64:
$(MAKE) $(ENAME) PLAT=mac_x64 -j$(JOBS)
freebsd: freebsd:
$(MAKE) $(ENAME) PLAT=freebsd -j$(JOBS) $(MAKE) $(ENAME) PLAT=freebsd -j$(JOBS)
openbsd: openbsd: