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

@@ -107,17 +107,19 @@ public:
delete_client(client);
return false;
}
// Security check.
if (inv.actor() != client->actor_id_) {
delete_client(client);
return false;
}
// util::dprint("Invoking: ", inv.debug_string());
world_->invoke(inv);
// Acknowledge the invocation.
client->channel_->out()->write_uint8(util::MSG_ACK);
client->channel_->out()->write_uint32(0);
client->sync_->invoke(inv);
client->async_diff_ = true;
// Process the invocation.
//
// 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;
}

View File

@@ -283,22 +283,80 @@ LuaDefine(tangible_delete, "tan",
"|Delete the specified tangible."
"|"
"|This cannot be used to delete player tangibles,"
"|To delete a player, use tangible.redirect") {
"|To delete a player, use tangible.redirect"
"|") {
LuaArg tanobj;
LuaDefStack LS(L, tanobj);
World *w = World::fetch_global_pointer(L);
Tangible *tan = w->tangible_get(LS, tanobj, true);
if (tan == nullptr) {
return LS.result();
luaL_error(L, "Not a tangible.");
return 0;
}
if (tan->is_an_actor()) {
luaL_error(L, "Cannot delete a player using tangible.delete, use tangible.redirect instead.");
if (tan->can_be_controlled_) {
luaL_error(L, "Cannot delete a player using tangible.delete, use tangible.deleteactor instead.");
return 0;
}
w->tangible_delete(tan->id());
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",
"|Build a new tangible object."
"|"
@@ -398,29 +456,6 @@ LuaDefine(tangible_get, "id",
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",
"|Return the tangible's id number."
"|This is for debugging only and will be removed"

View File

@@ -120,7 +120,6 @@ public:
int64_t id() const { return plane_item_.id(); }
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(); }
};

View File

@@ -14,7 +14,9 @@
static ReadlineDevice readline_device;
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) {

View File

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