Progress toward implementing redirect

This commit is contained in:
2026-05-27 17:13:32 -04:00
parent 779c9f5c2e
commit e1f3c81cbd
6 changed files with 76 additions and 48 deletions

View File

@@ -1,8 +1,6 @@
* Add a slash-command to reload lua source code.
* Skeletal Mesh Tangible * Skeletal Mesh Tangible
* Implement Interactive Temporary Variables * Implement Interactive Temporary Variables
@@ -15,16 +13,10 @@ Secret / semi-secret variables
Secret functions Secret functions
Unicode support for the console
Blockchain integration Blockchain integration
GUI that looks for verbs
More sophisticated passage of time More sophisticated passage of time
GUI that runs in realtime
Little game demos: Little game demos:
The monopoly game (Errands where you pass thru land owned by others with voronoi diagram) The monopoly game (Errands where you pass thru land owned by others with voronoi diagram)

View File

@@ -107,17 +107,19 @@ public:
delete_client(client); delete_client(client);
return false; return false;
} }
// Security check. // Acknowledge the invocation.
if (inv.actor() != client->actor_id_) {
delete_client(client);
return false;
}
// util::dprint("Invoking: ", inv.debug_string());
world_->invoke(inv);
client->channel_->out()->write_uint8(util::MSG_ACK); client->channel_->out()->write_uint8(util::MSG_ACK);
client->channel_->out()->write_uint32(0); client->channel_->out()->write_uint32(0);
client->sync_->invoke(inv); // Process the invocation.
client->async_diff_ = true; //
// An invoke with the wrong actor_id is quietly a noop. This is
// to make leeway for clients who have recently been redirected, and
// who may not know their new actor_id yet.
if (inv.actor() == client->actor_id_) {
world_->invoke(inv);
client->sync_->invoke(inv);
client->async_diff_ = true;
}
return true; return true;
} }

View File

@@ -283,22 +283,80 @@ LuaDefine(tangible_delete, "tan",
"|Delete the specified tangible." "|Delete the specified tangible."
"|" "|"
"|This cannot be used to delete player tangibles," "|This cannot be used to delete player tangibles,"
"|To delete a player, use tangible.redirect") { "|To delete a player, use tangible.redirect"
"|") {
LuaArg tanobj; LuaArg tanobj;
LuaDefStack LS(L, tanobj); LuaDefStack LS(L, tanobj);
World *w = World::fetch_global_pointer(L); World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, true); Tangible *tan = w->tangible_get(LS, tanobj, true);
if (tan == nullptr) { if (tan == nullptr) {
return LS.result(); luaL_error(L, "Not a tangible.");
return 0;
} }
if (tan->is_an_actor()) { if (tan->can_be_controlled_) {
luaL_error(L, "Cannot delete a player using tangible.delete, use tangible.redirect instead."); luaL_error(L, "Cannot delete a player using tangible.delete, use tangible.deleteactor instead.");
return 0; return 0;
} }
w->tangible_delete(tan->id()); w->tangible_delete(tan->id());
return LS.result(); return LS.result();
} }
LuaDefine(tangible_deleteactor, "tan",
"|Delete an actor tangible, or mark it for deletion on logout."
"|"
"|This function is used to delete an actor tangible."
"|"
"|If the actor is not currently logged in, then the tangible is"
"|immediately deleted. If the actor is logged in, then the tangible"
"|is marked as delete_on_disconnect, and the force_disconnect flag"
"|is set. This will cause the actor to cleanly disconnect, and then"
"|the deletion will take place."
"|") {
LuaArg tanobj;
LuaDefStack LS(L, tanobj);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, true);
if ((tan == nullptr) || (!tan->can_be_controlled_)) {
luaL_error(L, "Tangible is not an actor.");
return 0;
}
if (tan->is_controlled_) {
tan->delete_on_disconnect_ = true;
tan->force_disconnect_ = true;
} else {
w->tangible_delete(tan->id());
}
return LS.result();
}
LuaDefine(tangible_keepactor, "tan",
"|Mark an actor tangible to not 'delete_on_disconnect'."
"|"
"|When a client connects to the server, a login actor is created and the"
"|client is put in control of the login actor. The client typically"
"|controls the login actor just long enough to type his username and password."
"|Then, he is redirected to the real actor."
"|"
"|When the client is redirected to the real actor, the login actor is no longer"
"|needed. The login actor has the flag 'delete_on_disconnect', so when the"
"|client detaches from the login actor, it is garbage collected."
"|"
"|However, if the player clicks 'NEW PLAYER', then it is necessary to"
"|convert the login actor into a permanent actor. The most important step is to"
"|clear the delete_on_disconnect flag. That is what 'keepactor' does."
"|") {
LuaArg tanobj;
LuaDefStack LS(L, tanobj);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, true);
if ((tan == nullptr) || (!tan->can_be_controlled_)) {
luaL_error(L, "Tangible is not an actor.");
return 0;
}
tan->delete_on_disconnect_ = false;
return LS.result();
}
LuaDefine(tangible_build, "config", LuaDefine(tangible_build, "config",
"|Build a new tangible object." "|Build a new tangible object."
"|" "|"
@@ -398,29 +456,6 @@ LuaDefine(tangible_get, "id",
return LS.result(); return LS.result();
} }
LuaDefine(tangible_redirect, "tan1,tan2,bulldozetan1",
"|Redirect is not working yet") {
LuaArg actor1, actor2, bldz;
LuaDefStack LS(L, actor1, actor2, bldz);
World *w = World::fetch_global_pointer(L);
bool bulldoze = LS.ckboolean(bldz);
Tangible *tan1 = w->tangible_get(LS, actor1, false);
if (!tan1->is_an_actor()) {
luaL_error(L, "redirect source is not an actor");
}
if (LS.isnil(actor2)) {
w->redirects_[tan1->id()] = 0;
} else {
Tangible *tan2 = w->tangible_get(LS, actor2, false);
tan2->configure_id_pool_for_actor();
w->redirects_[tan1->id()] = tan2->id();
}
if (bulldoze) {
w->tangible_delete(tan1->id());
}
return LS.result();
}
LuaDefine(tangible_id, "tan", LuaDefine(tangible_id, "tan",
"|Return the tangible's id number." "|Return the tangible's id number."
"|This is for debugging only and will be removed" "|This is for debugging only and will be removed"

View File

@@ -120,7 +120,6 @@ public:
int64_t id() const { return plane_item_.id(); } int64_t id() const { return plane_item_.id(); }
void update_plane_item(); void update_plane_item();
bool is_an_actor() { return (id_player_pool_.get_fifo_capacity() > 0); }
void configure_id_pool_for_actor() { id_player_pool_.set_fifo_capacity(3); id_player_pool_.refill(); } void configure_id_pool_for_actor() { id_player_pool_.set_fifo_capacity(3); id_player_pool_.refill(); }
}; };

View File

@@ -14,7 +14,9 @@
static ReadlineDevice readline_device; static ReadlineDevice readline_device;
static void dprint_callback(const char *oneline, size_t size) { static void dprint_callback(const char *oneline, size_t size) {
readline_device.printline(std::string_view(oneline, size)); std::string wlog("LOG: ");
wlog += std::string_view(oneline, size);
readline_device.printline(wlog);
} }
static void if_error_print_and_exit(const std::string_view str) { static void if_error_print_and_exit(const std::string_view str) {

View File

@@ -79,8 +79,6 @@ function engio.getlookat()
return "" return ""
end end
print("Hello from login.lua")
function jp3() function jp3()
tangible.animate{tan=actor, anim={action="play", seq="jump"}} tangible.animate{tan=actor, anim={action="play", seq="jump"}}
tangible.animate{tan=actor, anim={action="play", seq="jump"}} tangible.animate{tan=actor, anim={action="play", seq="jump"}}