Originally Posted by
Razo[R]apiD
One could also write one in scripting. Doesn't have to be native
But of course would be less efficient.
Ok. I wrote something following this guide Build a Regex Engine...
But the result is very simple and weak. The asterisk (*) keyword is bugged and debugging the errors can be painful.
I think will be easier and better to embed an existing regex engine in the patch than do something in Morpheus, which can be very limited, inefficient and buggy.
main:
local.regex = local CreateListener;
local.regex.targetname = "Regex";
local.regex.path = ("global/regex.scr");
local.regex.matchOne = local.regex.path::matchOne;
local.regex.match = local.regex.path::match;
local.regex.search = local.regex.path::search;
// TEST
wait 2;
local.pattern = "ab?c";
local.text = "ac";
local.result = waitthread $Regex.search local.pattern local.text;
println ("=================");
println ("pattern: " + local.pattern);
println ("text: " + local.text);
println ("result: " + local.result); // 1/0 (true/false)
println ("=================");
end;
matchOne local.pattern local.text:
if (!local.pattern)
end 1; // Any text matches an empty pattern
if (!local.text)
end 0; // If the pattern is defined but the text is empty, there cannot be a match
if (local.pattern == ".")
end 1; // Any inputted text matches the wildcard
end (local.pattern == local.text);
match local.pattern local.text:
if (local.pattern == "")
end 1;
if (local.pattern == "$" && local.text == "")
end 1;
if (local.pattern.size > 1) {
if (local.pattern[1] == "?")
end (waitthread matchQuestion local.pattern local.text);
if (local.pattern[1] == "*")
end (waitthread matchStar local.pattern local.text);
}
end ((waitthread matchOne local.pattern[0] local.text[0]) && (waitthread match (waitthread Slice local.pattern 1) (waitthread Slice local.text 1)));
search local.pattern local.text:
if (local.pattern[0] == "^") {
end (waitthread match (waitthread Slice local.pattern 1) local.text);
} else {
// end (waitthread match (".*" + local.pattern) local.text);
for (local.i = 0; local.i < local.text.size; local.i++) {
if (waitthread match local.pattern (waitthread Slice local.text local.i)) {
end 1;
}
}
}
end 0;
matchQuestion local.pattern local.text:
end (((waitthread matchOne local.pattern[0] local.text[0]) && (waitthread match (waitthread Slice local.pattern 2) (waitthread Slice local.text 1))) || (waitthread match (waitthread Slice local.pattern 2) local.text));
matchStar local.pattern local.text:
end (((waitthread matchOne local.pattern[0] local.text[0]) && (waitthread match local.pattern (waitthread Slice local.text 1))) || (waitthread match (waitthread Slice local.pattern 2) local.text));
//==================================================
Slice local.string local.startIndex local.endIndex:
if (local.startIndex >= local.string.size) {
end "";
} else if (local.startIndex < 0) {
local.startIndex = 0;
}
if ((typeof local.endIndex)[0] != "i" || local.endIndex >= local.string.size || local.endIndex < local.startIndex) {
local.endIndex = local.string.size;
}
local.result = "";
for (local.i = local.startIndex; local.i < local.endIndex; local.i++) {
local.result += local.string[local.i];
}
end local.result;
Originally Posted by
RyBack
I'd rather create a whole new directory structure outside main dir than mess with the current one, since a lot of mods depend on it.
+1
Sor has something like that planned for his framework. I hope someday he will come back and finish it.
Code:
// Do main autoexec logic in this class...
// I need 1 main function that does executions of specified folders (with filter argument)
// -> use this if the execution happens only once (unlike the events..)
/*
autoexec/
-> scripts here are executed at all times
autoexec/ffa/
autoexec/tdm/
autoexec/rb/
autoexec/obj/
-> if the gametype changes, one can use $Map.SetGametype <int g_gametype> [string abbrev] to execute
the scripts in the folder specified by 'abbrev'; for the default gametypes one needn't specify an
abbreviation. If one does, however, it will be treated as a custom gametype.
-> if $Map.SetGametype is not called before level waittill spawn, it will be automatically called to
set the gametype to its default in accordance with g_gametype
autoexec/<bsp name>/
-> if there are script files for the current map, they will be run when the default mapscript is added.
autoexec/<bsp name>/cfg/
-> .cfg files here will be executed (using stuffsrv "exec ...")
*/
// connected <-> spawn event problem
// Only if the map changes, are the event registrations discarded...
// -> if before prespawn, do not re-register, otherwise go ahead?
// Additional autoexec stuff:
/*
autoexec/events/killed/
autoexec/events/damage/
autoexec/events/spawn/
autoexec/events/connect/
autoexec/events/disconnect/
autoexec/events/keypress/
autoexec/events/intermission/
autoexec/events/servercmd/
-> scripts to execute for each event. Events will only be registered only if their corresponding script folders aren't empty.
autoexec/states/stand/
autoexec/states/raise_weap/
-> scripts to execute for statefile events (entry as well as exit commands (use .entry and .exit as file extensions to differentiate (only check for .exit though))
*/
BTW, what happened with the Reborn pk3 framework project? The last time someone talked something about it in the forum was in 2013