Compare commits

...

6 Commits

18 changed files with 107 additions and 94 deletions

1
.gitattributes vendored
View File

@@ -13,6 +13,7 @@
*.jpg filter=lfs diff=lfs merge=lfs -text *.jpg filter=lfs diff=lfs merge=lfs -text
*.png filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text
*.psd filter=lfs diff=lfs merge=lfs -text *.psd filter=lfs diff=lfs merge=lfs -text
*.pdf filter=lfs diff=lfs merge=lfs -text
*.sln filter=lfs diff=lfs merge=lfs -text *.sln filter=lfs diff=lfs merge=lfs -text
*.uasset filter=lfs diff=lfs merge=lfs -text *.uasset filter=lfs diff=lfs merge=lfs -text
*.umap filter=lfs diff=lfs merge=lfs -text *.umap filter=lfs diff=lfs merge=lfs -text

View File

@@ -1,20 +0,0 @@
[/Script/UnrealEd.EditorStyleSettings]
AssetEditorOpenLocation=MainWindow
[/Script/BlueprintGraph.BlueprintEditorSettings]
SaveOnCompile=SoC_SuccessOnly
[/Script/UnrealEd.EditorLoadingSavingSettings]
RestoreOpenAssetTabsOnRestart=AlwaysRestore
AutoSaveWarningInSeconds=0
[/Script/Integration.lxProjectSettings]
ActiveServer=/Game/Luprex/KnownServers/SS_Localhost.SS_Localhost
[/Script/Integration.lxEditorSettings]
ActiveServer=/Game/Luprex/KnownServers/SS_Localhost.SS_Localhost

Binary file not shown.

Binary file not shown.

View File

@@ -2,6 +2,7 @@
#include "BreakToDebugger.h" #include "BreakToDebugger.h"
#include "Blueprint/BlueprintExceptionInfo.h" #include "Blueprint/BlueprintExceptionInfo.h"
#include "Kismet2/KismetDebugUtilities.h" #include "Kismet2/KismetDebugUtilities.h"
#include "LuprexEditorSettings.h"
ELogVerbosity::Type FlxBreakToDebuggerOutputDevice::ConvertThreshold(ElxBreakToDebuggerThreshold Verbosity) { ELogVerbosity::Type FlxBreakToDebuggerOutputDevice::ConvertThreshold(ElxBreakToDebuggerThreshold Verbosity) {
switch (Verbosity) { switch (Verbosity) {
@@ -15,8 +16,8 @@ ELogVerbosity::Type FlxBreakToDebuggerOutputDevice::ConvertThreshold(ElxBreakToD
} }
} }
FlxBreakToDebuggerOutputDevice::FlxBreakToDebuggerOutputDevice(const ElxBreakToDebuggerThreshold &SensitivityRef) FlxBreakToDebuggerOutputDevice::FlxBreakToDebuggerOutputDevice()
: Sensitivity(SensitivityRef) : Settings(GetDefault<UlxEditorSettings>())
{ {
GLog->AddOutputDevice(this); GLog->AddOutputDevice(this);
} }
@@ -48,7 +49,7 @@ void FlxBreakToDebuggerOutputDevice::Serialize(const TCHAR* V, ELogVerbosity::Ty
{ {
// If the error isn't serious enough, do nothing. // If the error isn't serious enough, do nothing.
// //
if (Verbosity > ConvertThreshold(Sensitivity)) if (Verbosity > ConvertThreshold(Settings->BreakToDebuggerLogVerbosity))
{ {
return; return;
} }
@@ -67,6 +68,13 @@ void FlxBreakToDebuggerOutputDevice::Serialize(const TCHAR* V, ELogVerbosity::Ty
UObject *TopObject = Frame->Object; UObject *TopObject = Frame->Object;
if (TopObject == nullptr) return; if (TopObject == nullptr) return;
// If the category is in the exclude list, do nothing.
//
if (Settings->BreakToDebuggerExcludeCategories.Contains(Category))
{
return;
}
// Notify the debugger that there's been an exception. // Notify the debugger that there's been an exception.
// //
FBlueprintExceptionInfo ExceptionInfo(EBlueprintExceptionType::Breakpoint, FText::FromStringView(FStringView(V))); FBlueprintExceptionInfo ExceptionInfo(EBlueprintExceptionType::Breakpoint, FText::FromStringView(FStringView(V)));

View File

@@ -79,19 +79,15 @@ enum class ElxBreakToDebuggerThreshold : uint8 {
}; };
class UlxEditorSettings;
struct FlxBreakToDebuggerOutputDevice : public FOutputDevice struct FlxBreakToDebuggerOutputDevice : public FOutputDevice
{ {
public: public:
// The constructor and destructor automatically register // The constructor and destructor automatically register
// this output device with GLog. // this output device with GLog.
// //
// This struct doesn't store the sensitivity threshold. FlxBreakToDebuggerOutputDevice();
// It relies on the LuprexGameMode class to do that, so
// that the threshold can be easily edited with the
// blueprint editor. This struct must be initialized
// with a reference to the threshold variable.
//
FlxBreakToDebuggerOutputDevice(const ElxBreakToDebuggerThreshold &SensitivityRef);
~FlxBreakToDebuggerOutputDevice(); ~FlxBreakToDebuggerOutputDevice();
// Inspect a log message. // Inspect a log message.
@@ -109,5 +105,5 @@ public:
private: private:
static ELogVerbosity::Type ConvertThreshold(ElxBreakToDebuggerThreshold Verbosity); static ELogVerbosity::Type ConvertThreshold(ElxBreakToDebuggerThreshold Verbosity);
const ElxBreakToDebuggerThreshold &Sensitivity; const UlxEditorSettings *Settings = nullptr;
}; };

View File

@@ -2,3 +2,4 @@
DEFINE_LOG_CATEGORY(LogLuprex); DEFINE_LOG_CATEGORY(LogLuprex);
DEFINE_LOG_CATEGORY(LogLuprexIntegration); DEFINE_LOG_CATEGORY(LogLuprexIntegration);
DEFINE_LOG_CATEGORY(LogLuprexConsole);

View File

@@ -153,3 +153,7 @@ DECLARE_LOG_CATEGORY_EXTERN(LogLuprex, Display, All);
// Messages about the Luprex integration with Unreal. // Messages about the Luprex integration with Unreal.
// //
DECLARE_LOG_CATEGORY_EXTERN(LogLuprexIntegration, Display, All); DECLARE_LOG_CATEGORY_EXTERN(LogLuprexIntegration, Display, All);
// Messages from the Luprex console.
//
DECLARE_LOG_CATEGORY_EXTERN(LogLuprexConsole, Display, All);

View File

@@ -1 +1,7 @@
#include "LuprexEditorSettings.h" #include "LuprexEditorSettings.h"
#include "Common.h"
UlxEditorSettings::UlxEditorSettings()
{
BreakToDebuggerExcludeCategories.Add(LogLuprexConsole.GetCategoryName());
}

View File

@@ -25,6 +25,8 @@ class INTEGRATION_API UlxEditorSettings : public UDeveloperSettings
GENERATED_BODY() GENERATED_BODY()
public: public:
UlxEditorSettings();
virtual FName GetContainerName() const override { return TEXT("Editor"); } virtual FName GetContainerName() const override { return TEXT("Editor"); }
virtual FName GetCategoryName() const override { return TEXT("Luprex"); } virtual FName GetCategoryName() const override { return TEXT("Luprex"); }
virtual FName GetSectionName() const override { return TEXT("Settings"); } virtual FName GetSectionName() const override { return TEXT("Settings"); }
@@ -39,5 +41,9 @@ public:
// severity, the blueprint debugger will automatically pause with a breakpoint. // severity, the blueprint debugger will automatically pause with a breakpoint.
UPROPERTY(Config, EditAnywhere, Category="Debugging Tools") UPROPERTY(Config, EditAnywhere, Category="Debugging Tools")
ElxBreakToDebuggerThreshold BreakToDebuggerLogVerbosity; ElxBreakToDebuggerThreshold BreakToDebuggerLogVerbosity;
// Log categories in this set are excluded from BreakToDebugger triggering.
UPROPERTY(Config, EditAnywhere, Category="Debugging Tools")
TSet<FName> BreakToDebuggerExcludeCategories;
}; };

View File

@@ -238,7 +238,7 @@ void ALuprexGameModeBase::InitializeGlobalState()
// If somebody generates a log message that's severe enough, break to debugger. // If somebody generates a log message that's severe enough, break to debugger.
BreakToDebuggerLogVerbosityDevice.Reset( BreakToDebuggerLogVerbosityDevice.Reset(
new FlxBreakToDebuggerOutputDevice(GetDefault<UlxEditorSettings>()->BreakToDebuggerLogVerbosity)); new FlxBreakToDebuggerOutputDevice());
} }
void ALuprexGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason) void ALuprexGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)

View File

@@ -242,3 +242,8 @@ void UlxUtilityLibrary::ValidateLuaExpr(
Status = w.ValidateLuaExpr(Code, ErrorMessage); Status = w.ValidateLuaExpr(Code, ErrorMessage);
} }
void UlxUtilityLibrary::LogLuprexConsoleMessage(const FString &Message)
{
UE_LOG(LogLuprexConsole, Warning, TEXT("%s"), *Message);
}

View File

@@ -144,4 +144,9 @@ public:
// //
UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Utility") UFUNCTION(BlueprintCallable, meta = (WorldContext = "context"), Category = "Luprex|Utility")
static void ValidateLuaExpr(ElxLuaSyntaxCheck &Status, FString &ErrorMessage, UObject *context, const FString &Code); static void ValidateLuaExpr(ElxLuaSyntaxCheck &Status, FString &ErrorMessage, UObject *context, const FString &Code);
// Log a message to the LogLuprexConsole category.
//
UFUNCTION(BlueprintCallable, Category = "Luprex|Utility")
static void LogLuprexConsoleMessage(const FString &Message);
}; };

View File

@@ -1,2 +0,0 @@
#define LUPREX_DLL_PATH "/home/teppy/integration/luprex/build/Linux/luprexlib.so"
#define LUPREX_ROOT_PATH "/home/teppy/integration/luprex"

View File

@@ -171,6 +171,7 @@ public:
LuaExtraArgs(int i, int s) : index_(i), size_(s) {} LuaExtraArgs(int i, int s) : index_(i), size_(s) {}
LuaSpecial operator[] (int n) const { return LuaSpecial(index_ + n); } LuaSpecial operator[] (int n) const { return LuaSpecial(index_ + n); }
int index(int n) const { return index_ + n; }
int size() const { return size_; } int size() const { return size_; }
friend class LuaCoreStack; friend class LuaCoreStack;

View File

@@ -607,20 +607,13 @@ LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
"|to continue running until it blocks. But from that point" "|to continue running until it blocks. But from that point"
"|forward, the thread will never be resumed for any reason.") { "|forward, the thread will never be resumed for any reason.") {
int top = lua_gettop(L);
if (top < 2) {
luaL_error(L, "Not enough arguments to tangible.start");
return 0;
}
int varlen = top - 2;
World *w = World::fetch_global_pointer(L); World *w = World::fetch_global_pointer(L);
w->guard_blockable(L, "tangible.start"); w->guard_blockable(L, "tangible.start");
LuaArg place, fname;
LuaExtraArgs extra;
LuaVar mt, classtab, plthreads, thread, thinfo, func, tanlist; LuaVar mt, classtab, plthreads, thread, thinfo, func, tanlist;
LuaDefStack LS(L, mt, classtab, plthreads, thread, thinfo, func, tanlist); LuaDefStack LS(L, place, fname, extra, mt, classtab, plthreads, thread, thinfo, func, tanlist);
LuaSpecial place(1);
LuaSpecial fname(2);
// If they passed in a single tangible, convert it to a tangible list. // If they passed in a single tangible, convert it to a tangible list.
int64_t place_id = LS.tanid(place); int64_t place_id = LS.tanid(place);
@@ -677,10 +670,10 @@ LuaDefine(tangible_start, "tangible,function,arg1,arg2...",
// Create a new thread, set up function and arguments. // Create a new thread, set up function and arguments.
lua_State *CO = LS.newthread(thread); lua_State *CO = LS.newthread(thread);
lua_pushvalue(L, func.index()); lua_pushvalue(L, func.index());
for (int i = 0; i < varlen; i++) { for (int i = 0; i < extra.size(); i++) {
lua_pushvalue(L, i + 3); lua_pushvalue(L, extra.index(i));
} }
lua_xmove(L, CO, varlen + 1); lua_xmove(L, CO, extra.size() + 1);
// Create the thread info table. // Create the thread info table.
LS.newtable(thinfo); LS.newtable(thinfo);

View File

@@ -310,10 +310,13 @@ int64_t World::connection_create() {
assert(stack_is_clear()); assert(stack_is_clear());
int64_t id = id_global_pool_.get_one(); int64_t id = id_global_pool_.get_one();
{ {
LuaVar database, classtab, mt, func; LuaVar database, classtab, config, mt, func;
LuaExtStack LS(state(), database, classtab, mt, func); LuaExtStack LS(state(), database, classtab, config, mt, func);
Tangible *tan = tangible_make(LS, database, id); Tangible *tan = tangible_make(LS, database, id);
// A blank config table to pass to 'init'
LS.newtable(config);
// Set the login flags. // Set the login flags.
if (is_authoritative()) { if (is_authoritative()) {
tan->client_id_ = id; tan->client_id_ = id;
@@ -327,7 +330,9 @@ int64_t World::connection_create() {
if (is_authoritative()) { if (is_authoritative()) {
LS.rawget(func, classtab, "init"); LS.rawget(func, classtab, "init");
spawn(LS, id, id, func, 0, false); lua_pushvalue(state(), database.index());
lua_pushvalue(state(), config.index());
spawn(LS, id, id, func, 2, false);
} }
} }
connections_.emplace(id, id); connections_.emplace(id, id);
@@ -977,13 +982,18 @@ void World::invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_vi
if (errors.empty()) { if (errors.empty()) {
{ {
lua_State *L = state(); lua_State *L = state();
LuaVar lclass, lfunc; LuaVar lclass, lfunc, tangibles, actor, config;
LuaExtStack LS(L, lclass, lfunc); LuaExtStack LS(L, lclass, lfunc, tangibles, actor, config);
LS.rawget(tangibles, LuaRegistry, "tangibles");
LS.rawget(actor, tangibles, actor_id);
LS.newtable(config);
LS.getclass(lclass, "world"); LS.getclass(lclass, "world");
if (LS.classname(lclass) != "") { if (LS.classname(lclass) != "") {
LS.rawget(lfunc, lclass, "init"); LS.rawget(lfunc, lclass, "init");
spawn(LS, actor_id, place_id, lfunc, 0, false); lua_pushvalue(L, actor.index());
lua_pushvalue(L, config.index());
spawn(LS, actor_id, place_id, lfunc, 2, false);
} }
} }
run_scheduled_threads(); run_scheduled_threads();

View File

@@ -32,21 +32,20 @@ end
-- tangible.delete(actor) -- If actor is a connected player it will disconnect -- tangible.delete(actor) -- If actor is a connected player it will disconnect
-- This gets called on every login except the admin user. -- This gets called on every login except the admin user.
function login.init() function login.init(self, config)
local player = global.get("nextplayer") local player = global.get("nextplayer")
global.set("nextplayer", player + 1) global.set("nextplayer", player + 1)
dprint("login.init initializing player ", player) printf("login.init initializing %p, player %d", self, player)
actor.player = player self.player = player
tangible.keepactor(actor) -- do not delete this login when the client disconnects self.color={0,0,0,0,0,0,0,0,0,0,0,0}
actor.color={0,0,0,0,0,0,0,0,0,0,0,0} self.kills=0
actor.kills=0 self.killed=0
actor.killed=0 tangible.animinit{tan=self, anim={bp="character", mesh="manny", plane="earth", xyz={player * 100, 0, 90}}}
tangible.animinit{tan=actor, anim={bp="character", mesh="manny", plane="earth", xyz={player * 100, 0, 90}}} tangible.start(self, login.startscanning)
dprint("About to start scanning")
actor.startscanning()
end end
function login.startscanning() function login.startscanning()
printf("Scanning started. Actor=%p Place=%p", actor, place)
while true do while true do
login.onescan() login.onescan()
wait(1) wait(1)
@@ -75,13 +74,13 @@ function login.onescan()
end end
-- This gets called on the admin user. You can call login.init in here if you want. -- This gets called on the admin user. You can call login.init in here if you want.
function world.init() function world.init(self, config)
dprint("world.init") print("world.init")
global.set("nextplayer", 0) global.set("nextplayer", 0)
tangible.build{class=roster, anim={plane="earth", xyz={2000,0,0} } } tangible.build{class=roster, anim={plane="earth", xyz={2000,0,0} } }
tangible.build{class=cube, anim={plane="earth", xyz={500,-100,0}, mat_color={1,0,0}}} tangible.build{class=cube, anim={plane="earth", xyz={500,-100,0}, mat_color={1,0,0}}}
tangible.build{class=sphere, anim={plane="earth", xyz={500,100,0}, mat_color={0,0,1}}} tangible.build{class=sphere, anim={plane="earth", xyz={500,100,0}, mat_color={0,0,1}}}
login.init() login.init(self, config)
end end
@@ -90,7 +89,7 @@ function roster.init(self,config)
end end
function world.buildpylon() function world.buildpylon()
dprint("Building pylon") print("Building pylon")
local radius=1000 local radius=1000
tangible.build{class=pylon,plane="earth",xyz={math.random(-radius,radius),math.random(-radius,radius),0}}.color=math.random(1,12) tangible.build{class=pylon,plane="earth",xyz={math.random(-radius,radius),math.random(-radius,radius),0}}.color=math.random(1,12)
end end
@@ -111,29 +110,29 @@ end
-- Four cases: Unnamed to new, Unnamed to existing, Named to new, Named to Existing -- Four cases: Unnamed to new, Unnamed to existing, Named to new, Named to Existing
function playas(who) function playas(who)
dprintf("Playas %lP",place) printf("Playas %lP",place)
if not actor.name and not place.character[who] then -- Unnamed to new if not actor.name and not place.character[who] then -- Unnamed to new
dprintf("Case 1: Naming this character "..who) printf("Case 1: Naming this character "..who)
actor.name=who actor.name=who
tangible.keepactor(actor) tangible.keepactor(actor)
place.character[who]=actor place.character[who]=actor
elseif actor.name and not place.character[who] then -- Named to new (Hard one) elseif actor.name and not place.character[who] then -- Named to new (Hard one)
dprintf("Case 2: Creating new character "..who) printf("Case 2: Creating new character "..who)
dprintf("Case 2.0") printf("Case 2.0")
local nc=tangible.build{class=login, anim={plane="earth", xyz={0,0,0} } } local nc=tangible.build{class=login, anim={plane="earth", xyz={0,0,0} } }
dprintf("Case 2.1") printf("Case 2.1")
nc.name=who nc.name=who
dprintf("Case 2.2") printf("Case 2.2")
tangible.keepactor(nc) tangible.keepactor(nc)
dprintf("Case 2.3") printf("Case 2.3")
place.character[who]=nc place.character[who]=nc
dprintf("Case 2.4: ...Place is now "..place) printf("Case 2.4: ...Place is now "..place)
tangible.redirect(actor,nc) tangible.redirect(actor,nc)
elseif not actor.name and place.character[who] then elseif not actor.name and place.character[who] then
dprintf("Case 3: Logging in from unnamed to existing character "..who) printf("Case 3: Logging in from unnamed to existing character "..who)
tangible.redirect(actor,place.character[who]) tangible.redirect(actor,place.character[who])
elseif actor.name and place.character[who] then elseif actor.name and place.character[who] then
dprintf("Case 4: Logging in from "..actor.name.." to existing character "..who) printf("Case 4: Logging in from "..actor.name.." to existing character "..who)
tangible.redirect(actor,place.character[who]) tangible.redirect(actor,place.character[who])
end end
end end
@@ -145,24 +144,24 @@ function roster.lookmenu(add)
end end
function cube.lookmenu(add) function cube.lookmenu(add)
add("Cube A", function () dprint("Doing Cube A") end) add("Cube A", function () print("Doing Cube A") end)
add("Cube B", function () dprint("Doing Cube B") end) add("Cube B", function () print("Doing Cube B") end)
add("Cube C", function () dprint("Doing Cube C") end) add("Cube C", function () print("Doing Cube C") end)
add("Cube Hi", function () dprint("Doing Cube Hi") end) add("Cube Hi", function () print("Doing Cube Hi") end)
add("Cube Bye", function () dprint("Doing Cube Bye") end) add("Cube Bye", function () print("Doing Cube Bye") end)
add("Cube Yo", function () dprint("Doing Cube Yo") end) add("Cube Yo", function () print("Doing Cube Yo") end)
add("Cube Z", function () dprint("Doing Cube Z") end) add("Cube Z", function () print("Doing Cube Z") end)
end end
function sphere.lookhotkeys(add) function sphere.lookhotkeys(add)
add("FaceL", "Sphere Hi", function () dprint("Doing Sphere Hi") end) add("FaceL", "Sphere Hi", function () print("Doing Sphere Hi") end)
add("FaceM", "Sphere Bye", function () dprint("Doing Sphere Bye") end) add("FaceM", "Sphere Bye", function () print("Doing Sphere Bye") end)
add("FaceR", "Sphere Yo", function () dprint("Doing Sphere Yo") end) add("FaceR", "Sphere Yo", function () print("Doing Sphere Yo") end)
end end
function sphere.tick(foo) function sphere.tick(foo)
dprint("Tick") print("Tick")
end end