1
0
forked from redo/BlockLua
Files
BlockLua/src/util/loadaddons.cs
2025-10-01 16:26:18 -07:00

413 lines
13 KiB
C#

// Package to allow add-ons to use server.lua or client.lua
// instead of or in addition to server.cs or client.cs
// Relevant .lua files are is executed before .cs files.
function _bllua_strEndsWith(%str, %sch) {
%schL = strLen(%sch);
return getSubStr(%str, strLen(%str)-%schL, %schL) $= %sch;
}
//function _bllua_strRemoveEnd(%str, %sch) {
// %schL = strLen(%sch);
// return getSubStr(%str, 0, strLen(%str)-%schL);
//}
function _bllua_fileIsExecCs(%fn) {
return
_bllua_strEndsWith(%fn, "/server.cs" ) ||
_bllua_strEndsWith(%fn, "/server.lua") ||
_bllua_strEndsWith(%fn, "/client.cs" ) ||
_bllua_strEndsWith(%fn, "/client.lua");
}
function _bllua_execAddon(%dirName, %type) {
%i = 0;
%fnLua = "Add-Ons/" @ %dirName @ "/" @ %type @ ".lua";
if(isFile(%fnLua)) { luaexec(%fnLua); %i++; }
%fnCs = "Add-Ons/" @ %dirName @ "/" @ %type @ ".cs";
if(isFile(%fnCs )) { exec(%fnCs ); %i++; }
if(%i==0) {
error("Error Loading Add-On " @ %dirName @ ": Neither " @
%type @ ".cs nor " @ %type @ ".lua exist");
}
}
// Rewrite built-in functions that scan for server.cs or client.cs
// and make them scan for server.lua or client.lua as well
// Note: I had to completely override several large functions,
// many of which are highly redundant, because Badspot didn't know
// what functional decomposition was when he wrote this shit.
package _bllua_addon_exec {
function CustomGameGuiServer::populateAddOnList() {
deleteVariables("$CustomGameGuiServer::AddOn*");
$CustomGameGuiServer::AddOnCount = 0;
%pattern = "Add-Ons/*/server.*";
%filename = findFirstFile(%pattern);
while(isFile(%filename)) {
if(_bllua_fileIsExecCs(%filename)) {
%path = filePath(%filename);
%dirName = getSubStr(%path, strlen("Add-Ons/"), strlen(%path) - strlen("Add-Ons/"));
if(!%seenDirName[%dirName]) {
%seenDirName[%dirName] = 1;
%varName = getSafeVariableName(%dirName);
if(isValidAddOn(%dirName, 1)) {
$CustomGameGuiServer::AddOn[$CustomGameGuiServer::AddOnCount] = %dirName;
$CustomGameGuiServer::AddOnCount++;
}
}
}
%filename = findNextFile(%pattern);
}
}
function GameModeGuiServer::GetMissingAddOns(%filename) {
if(!isFile(%filename)) {
error("ERROR: GameModeGuiServer::GetMissingAddOns(" @ %filename @ ") - file does not exist");
return 0;
}
%path = filePath(%filename);
%missingAddons = "";
%descriptionFile = %path @ "/description.txt";
%previewFile = %path @ "/preview.jpg";
%thumbFile = %path @ "/thumb.jpg";
%saveFile = %path @ "/save.bls";
%colorSetFile = %path @ "/colorSet.txt";
if(!isFile(%descriptionFile))
%missingAddons = %missingAddons TAB %descriptionFile;
if(!isFile(%previewFile))
%missingAddons = %missingAddons TAB %previewFile;
if(!isFile(%thumbFile))
%missingAddons = %missingAddons TAB %thumbFile;
if(!isFile(%saveFile))
%missingAddons = %missingAddons TAB %saveFile;
if(!isFile(%colorSetFile))
%missingAddons = %missingAddons TAB %colorSetFile;
%file = new FileObject(""){};
%file.openForRead(%filename);
while(!%file.isEOF()) {
%line = %file.readLine();
%label = getWord(%line, 0);
%value = trim(getWords(%line, 1, 999));
if(%label !$= "") {
if(getSubStr(%label, 0, 2) !$= "//") {
if(%label $= "ADDON") {
if(!isFile("Add-Ons/" @ %value @ "/description.txt") ||
(!isFile("Add-Ons/" @ %value @ "/server.cs" ) &&
!isFile("Add-Ons/" @ %value @ "/server.lua") ) ) {
if(strlen(%missingAddons) > 0)
%missingAddons = %missingAddons TAB %value;
else
%missingAddons = %value;
}
} else {
if(%label $= "MUSIC") {
if(!isFile("Add-Ons/Music/" @ %value @ ".ogg")) {
if(strlen(%missingAddons) > 0)
%missingAddons = %missingAddons TAB %value @ ".ogg";
else
%missingAddons = %value;
}
}
}
}
}
}
%file.close();
%file.delete();
return %missingAddons;
}
function loadAddOns() {
echo("");
updateAddOnList();
echo("--------- Loading Add-Ons (+BlockLua) ---------");
deleteVariables("$AddOnLoaded__*");
%dir = "Add-Ons/*/server.*";
%filename = findFirstFile(%dir);
%dirCount = 0;
if(isFile("Add-Ons/System_ReturnToBlockland/server.cs")) {
%dirNameList[%dirCount] = "System_ReturnToBlockland";
%dirCount++;
}
while(%filename !$= "") {
if(_bllua_fileIsExecCs(%filename)) {
%path = filePath(%filename);
%dirName = getSubStr(%path, strlen("Add-Ons/"), strlen(%path) - strlen("Add-Ons/"));
if(!%seenDirName[%dirName]) {
%seenDirName[%dirName] = 1;
if(%dirName !$= "System_ReturnToBlockland") {
%dirNameList[%dirCount] = %dirName;
%dirCount++;
}
}
}
%filename = findNextFile(%dir);
}
for(%addOnItr = 0; %addOnItr < %dirCount; %addOnItr++) {
%dirName = %dirNameList[%addOnItr];
%varName = getSafeVariableName(%dirName);
if(!$Server::Dedicated) {
if(getRealTime() - $lastProgressBarTime > 200) {
LoadingProgress.setValue(%addOnItr / %dirCount);
$lastProgressBarTime = getRealTime();
Canvas.repaint();
}
}
if($AddOn__[%varName] $= 1 && isValidAddOn(%dirName)) {
if(%dirName $= "JVS_Content" && $AddOn__["Support_LegacyDoors"] $= 1) {
echo(" Skipping JVS_Content in favor of Support_LegacyDoors");
} else if(!$AddOnLoaded__[%varName]) {
$AddOnLoaded__[%varName] = 1;
%zipFile = "Add-Ons/" @ %dirName @ ".zip";
if(isFile(%zipFile)) {
%zipCRC = getFileCRC(%zipFile);
echo("\c5Loading Add-On: " @ %dirName @ " \c2(CRC:" @ %zipCRC @ ")");
} else {
echo("\c5Loading Add-On: " @ %dirName);
}
if(VerifyAddOnScripts(%dirName)==0) {
echo("\c3ADD-ON " @ %dirName @ " CONTAINS SYNTAX ERRORS\n");
} else {
%oldDBCount = DataBlockGroup.getCount();
_bllua_execAddon(%dirName, "server");
%dbDiff = DataBlockGroup.getCount() - %oldDBCount;
echo("\c2" @ %dbDiff @ " datablocks added.");
echo("");
}
}
}
}
echo("");
}
function loadGameModeAddOns() {
echo("");
echo("--------- Loading Add-Ons (Game Mode) (+BlockLua) ---------");
deleteVariables("$AddOnLoaded__*");
for(%i=0; %i<$GameMode::AddOnCount; %i++) {
%dirName = $GameMode::AddOn[%i];
%varName = getSafeVariableName(%dirName);
if(!$Server::Dedicated) {
if(getRealTime() - $lastProgressBarTime > 200) {
LoadingProgress.setValue(%i / $GameMode::AddOnCount);
$lastProgressBarTime = getRealTime();
Canvas.repaint();
}
}
if(!isValidAddOn(%dirName)) {
error("ERROR: Invalid add-on \'" @ %dirName @ "\' specified for game mode \'" @ $GameModeArg @ "\'");
} else {
$AddOnLoaded__[%varName] = 1;
%zipFile = "Add-Ons/" @ %dirName @ ".zip";
if(isFile(%zipFile)) {
%zipCRC = getFileCRC(%zipFile);
echo("\c5Loading Add-On: " @ %dirName @ " \c2(CRC:" @ %zipCRC @ ")");
} else {
echo("\c5Loading Add-On: " @ %dirName);
}
if(VerifyAddOnScripts(%dirName) == 0) {
echo("\c3ADD-ON " @ %dirName @ " CONTAINS SYNTAX ERRORS\n");
} else {
%oldDBCount = DataBlockGroup.getCount();
_bllua_execAddon(%dirName, "server");
%dbDiff = DataBlockGroup.getCount() - %oldDBCount;
echo("\c2" @ %dbDiff @ " datablocks added.");
echo("");
}
}
}
echo("");
}
function loadClientAddOns() {
echo("");
echo("--------- Loading Client Add-Ons (+BlockLua) ---------");
if(isFile("base/server/crapOns_Cache.cs"))
exec("base/server/crapOns_Cache.cs");
%dir = "Add-Ons/*/client.*";
%filename = findFirstFile(%dir);
%dirCount = 0;
if(isFile("Add-Ons/System_ReturnToBlockland/client.cs")) {
%dirNameList[%dirCount] = "System_ReturnToBlockland";
%dirCount++;
}
while(%filename !$= "") {
if(_bllua_fileIsExecCs(%filename)) {
%path = filePath(%filename);
%dirName = getSubStr(%path, strlen("Add-Ons/"), strlen(%path) - strlen("Add-Ons/"));
if(!%seenDirName[%dirName]) {
%seenDirName[%dirName] = 1;
if(%dirName !$= "System_ReturnToBlockland") {
%dirNameList[%dirCount] = %dirName;
%dirCount++;
}
}
}
%filename = findNextFile(%dir);
}
for(%i=0; %i<%dirCount; %i++) {
%dirName = %dirNameList[%i];
%varName = getSafeVariableName(%dirName);
echo("");
echo("Client checking Add-On: " @ %dirName);
if(!clientIsValidAddOn(%dirName, 1)) {
//deleteVariables("$AddOn__" @ %varName); // wtf
} else {
%name = %dirName;
%zipFile = "Add-Ons/" @ %dirName @ ".zip";
if(isFile(%zipFile)) {
%zipCRC = getFileCRC(%zipFile);
echo("\c5Loading Add-On: " @ %dirName @ " \c2(CRC:" @ %zipCRC @ ")");
} else {
echo("\c5Loading Add-On: " @ %dirName);
}
if(ClientVerifyAddOnScripts(%dirName)==0)
echo("\c3ADD-ON " @ %dirName @ " CONTAINS SYNTAX ERRORS\n");
else
_bllua_execAddon(%dirName, "client");
}
}
echo("");
}
function updateAddOnList() {
echo("\n--------- Updating Add-On List (+BlockLua) ---------");
deleteVariables("$AddOn__*");
if(isFile("config/server/ADD_ON_LIST.cs")) {
exec("config/server/ADD_ON_LIST.cs");
} else {
exec("base/server/defaultAddOnList.cs");
}
if(isFile("base/server/crapOns_Cache.cs")) {
exec("base/server/crapOns_Cache.cs");
}
%dir = "Add-Ons/*/server.*";
%fileCount = getFileCount(%dir);
%filename = findFirstFile(%dir);
while(%filename !$= "") {
if(_bllua_fileIsExecCs(%filename)) {
%path = filePath(%filename);
%dirName = getSubStr(%path, strlen("Add-Ons/"), strlen(%path) - strlen("Add-Ons/"));
if(!%seenDirName[%dirName]) {
%seenDirName[%dirName] = 1;
%varName = getSafeVariableName(%dirName);
echo("Checking Add-On " @ %dirName);
if(!isValidAddOn(%dirName, 1)) {
deleteVariables("$AddOn__" @ %varName);
} else {
if (mFloor($AddOn__[%varName]) <= 0)
$AddOn__[%varName] = -1;
else
$AddOn__[%varName] = 1;
}
}
}
%filename = findNextFile(%dir);
}
echo("");
export("$AddOn__*", "config/server/ADD_ON_LIST.cs");
}
};
activatePackage(_bllua_addon_exec);
// Have to make new versions of these because packaging them is blocked FSFR
function forceRequiredAddOn_L(%dirName) {
if(%dirName $= "JVS_Content") {
if($GameModeArg $= "") {
if($AddOn__["Support_LegacyDoors"] == 1 || !isFile("add-ons/JVS_Content/server.cs") || ($AddOn__["Support_LegacyDoors"] != 1 && $AddOn__["JVS_Content"] != 1)) {
%dirName = "Support_LegacyDoors";
}
} else {
%foundJVSContent = 0;
for(%i=0; %i<$GameMode::AddOnCount; %i++) {
if ($GameMode::AddOn[%i] $= "JVS_Content") {
%foundJVSContent = 1;
}
}
if(!%foundJVSContent)
%dirName = "Support_LegacyDoors";
}
}
if(strstr(%dirName, " ") != -1)
%dirName = strreplace(%dirName, " ", "_");
//if(strstr(%dirName, "/") != -1)
// return $Error::AddOn_Nested;
%varName = getSafeVariableName(%dirName);
if($GameModeArg !$= "") {
%foundIt = 0;
for(%i=0; %i<$GameMode::AddOnCount; %i++) {
if ($GameMode::AddOn[%i] $= %dirName) {
%foundIt = 1;
break;
}
}
if(!%foundIt) {
error("ERROR: ForceRequiredAddOn_L(\'" @ %dirName @ "\') - you can\'t force load an add-on that is not included in gamemode.txt");
if (GameWindowExists() && !$Server::Dedicated) {
schedule(11, 0, MessageBoxOK, "Game Mode Error", "Required add-on " @ %dirName @ " should be added to gamemode.txt");
}
if (!isEventPending($disconnectEvent)) {
$disconnectEvent = schedule(10, 0, disconnect);
}
return $Error::AddOn_NotFound;
}
}
if($AddOnLoaded__[%varName] == 1)
return $Error::None;
if($AddOn__[%varName] $= "" && $GameModeArg $= "" || !isValidAddOn(%dirName)) {
error("ERROR: ForceRequiredAddOn() - " @ %dirName @ " is not a valid add-on");
return $Error::AddOn_NotFound;
}
echo(" Loading Add-On " @ %dirName @ "");
_bllua_execAddon(%dirName, "server");
$AddOnLoaded__[%varName] = 1;
if($AddOn__[%varName] $= 1)
return $Error::None;
else
return $Error::AddOn_Disabled;
}
function loadRequiredAddOn_L(%dirName) {
if(%dirName $= "JVS_Content") {
if($GameModeArg $= "") {
if($AddOn__["Support_LegacyDoors"] == 1 || !isFile("add-ons/JVS_Content/server.cs") || ($AddOn__["Support_LegacyDoors"] != 1 && $AddOn__["JVS_Content"] != 1)) {
%dirName = "Support_LegacyDoors";
}
} else {
%foundJVSContent = 0;
for(%i=0; %i<$GameMode::AddOnCount; %i++) {
if ($GameMode::AddOn[%i] $= "JVS_Content") {
%foundJVSContent = 1;
}
}
if(!%foundJVSContent)
%dirName = "Support_LegacyDoors";
}
}
if(strstr(%dirName, " ") != -1)
%dirName = strreplace(%dirName, " ", "_");
//if(strstr(%dirName, "/") != -1)
// return $Error::AddOn_Nested;
%varName = getSafeVariableName(%dirName);
if ($GameModeArg !$= "") {
%foundIt = 0;
for(%i=0; %i<$GameMode::AddOnCount; %i++) {
if ($GameMode::AddOn[%i] $= %dirName) {
%foundIt = 1;
break;
}
}
if(!%foundIt) {
error("ERROR: LoadRequiredAddOn_L(\'" @ %dirName @ "\') - you can\'t force load an add-on that is not included in gamemode.txt");
if (GameWindowExists() && !$Server::Dedicated)
schedule(11, 0, MessageBoxOK, "Game Mode Error", "Required add-on " @ %dirName @ " should be added to gamemode.txt");
if (!isEventPending($disconnectEvent))
$disconnectEvent = schedule(10, 0, disconnect);
return $Error::AddOn_NotFound;
}
}
if($AddOnLoaded__[%varName] == 1)
return $Error::None;
if($AddOn__[%varName] $= 1) {
echo(" Loading Add-On " @ %dirName @ "");
_bllua_execAddon(%dirName, "server");
$AddOnLoaded__[%varName] = 1;
return $Error::None;
} else {
return $Error::AddOn_Disabled;
}
}
echo(" Executed loadaddons.cs");