Better login handling
This commit is contained in:
@@ -13,5 +13,5 @@ RestoreOpenAssetTabsOnRestart=AlwaysRestore
|
|||||||
AutoSaveWarningInSeconds=0
|
AutoSaveWarningInSeconds=0
|
||||||
|
|
||||||
[/Script/Integration.lxProjectSettings]
|
[/Script/Integration.lxProjectSettings]
|
||||||
ActiveServer=/Game/Luprex/KnownServers/SS_Standalone.SS_Standalone
|
ActiveServer=/Game/Luprex/KnownServers/SS_Localhost.SS_Localhost
|
||||||
|
|
||||||
|
|||||||
@@ -282,8 +282,6 @@ LuaDefine(tangible_getclass, "tan",
|
|||||||
LuaDefine(tangible_delete, "tan",
|
LuaDefine(tangible_delete, "tan",
|
||||||
"|Delete the specified tangible."
|
"|Delete the specified tangible."
|
||||||
"|"
|
"|"
|
||||||
"|This cannot be used to delete actor tangibles,"
|
|
||||||
"|To delete a actor, use tangible.deleteactor"
|
|
||||||
"|") {
|
"|") {
|
||||||
LuaArg tanobj;
|
LuaArg tanobj;
|
||||||
LuaDefStack LS(L, tanobj);
|
LuaDefStack LS(L, tanobj);
|
||||||
@@ -293,12 +291,7 @@ LuaDefine(tangible_delete, "tan",
|
|||||||
luaL_error(L, "Not a tangible.");
|
luaL_error(L, "Not a tangible.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (tan->is_controlled_) {
|
w->tangible_delete(tan->id());
|
||||||
tan->delete_on_disconnect_ = true;
|
|
||||||
w->connection_redirect(tan, nullptr);
|
|
||||||
} else {
|
|
||||||
w->tangible_delete(tan->id());
|
|
||||||
}
|
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,10 +317,6 @@ LuaDefine(tangible_keepactor, "tan",
|
|||||||
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) || (!tan->is_controlled_)) {
|
|
||||||
luaL_error(L, "Tangible is not an actor.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
tan->delete_on_disconnect_ = false;
|
tan->delete_on_disconnect_ = false;
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
@@ -352,13 +341,11 @@ LuaDefine(tangible_redirect, "actor1, actor2",
|
|||||||
World *w = World::fetch_global_pointer(L);
|
World *w = World::fetch_global_pointer(L);
|
||||||
Tangible *actor1 = w->tangible_get(LS, lactor1, true);
|
Tangible *actor1 = w->tangible_get(LS, lactor1, true);
|
||||||
Tangible *actor2 = w->tangible_get(LS, lactor2, true);
|
Tangible *actor2 = w->tangible_get(LS, lactor2, true);
|
||||||
eng::string error = w->connection_redirect(actor1, actor2);
|
if (actor1->client_id_ == 0) {
|
||||||
if (!error.empty()) {
|
luaL_error(L, "actor1 is not currently logged in.");
|
||||||
eng::ostringstream oss;
|
|
||||||
oss << "redirect from " << actor1->id() << " to " << actor2->id() << " failed: " << error;
|
|
||||||
luaL_error(L, "%s", oss.str().c_str());
|
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
w->connection_redirect(actor1, actor2);
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,14 +358,8 @@ LuaDefine(tangible_forcedisconnect, "actor",
|
|||||||
LuaDefStack LS(L, lactor1, lactor2);
|
LuaDefStack LS(L, lactor1, lactor2);
|
||||||
World *w = World::fetch_global_pointer(L);
|
World *w = World::fetch_global_pointer(L);
|
||||||
Tangible *actor = w->tangible_get(LS, lactor1, true);
|
Tangible *actor = w->tangible_get(LS, lactor1, true);
|
||||||
if (actor->is_controlled_) {
|
if (actor->client_id_ != 0) {
|
||||||
eng::string error = w->connection_redirect(actor, nullptr);
|
w->connection_delete(actor->client_id_);
|
||||||
if (!error.empty()) {
|
|
||||||
eng::ostringstream oss;
|
|
||||||
oss << "forcedisconnect of " << actor->id() << " failed: " << error;
|
|
||||||
luaL_error(L, "%s", oss.str().c_str());
|
|
||||||
return LS.result();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return LS.result();
|
return LS.result();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -152,7 +152,7 @@ void Tangible::serialize(StreamBuffer *sb) {
|
|||||||
anim_queue_.serialize(sb);
|
anim_queue_.serialize(sb);
|
||||||
id_player_pool_.serialize(sb);
|
id_player_pool_.serialize(sb);
|
||||||
print_buffer_.serialize(sb);
|
print_buffer_.serialize(sb);
|
||||||
sb->write_bool(is_controlled_);
|
sb->write_int64(client_id_);
|
||||||
sb->write_bool(delete_on_disconnect_);
|
sb->write_bool(delete_on_disconnect_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,7 +160,7 @@ void Tangible::deserialize(StreamBuffer *sb) {
|
|||||||
anim_queue_.deserialize(sb);
|
anim_queue_.deserialize(sb);
|
||||||
id_player_pool_.deserialize(sb);
|
id_player_pool_.deserialize(sb);
|
||||||
print_buffer_.deserialize(sb);
|
print_buffer_.deserialize(sb);
|
||||||
is_controlled_ = sb->read_bool();
|
client_id_ = sb->read_int64();
|
||||||
delete_on_disconnect_ = sb->read_bool();
|
delete_on_disconnect_ = sb->read_bool();
|
||||||
update_plane_item();
|
update_plane_item();
|
||||||
}
|
}
|
||||||
@@ -216,7 +216,7 @@ Tangible *World::tangible_make(const LuaCoreStack &LS0, LuaSlot database, int64_
|
|||||||
t.reset(new Tangible(this, id));
|
t.reset(new Tangible(this, id));
|
||||||
|
|
||||||
// Set the login flags.
|
// Set the login flags.
|
||||||
t->is_controlled_ = false;
|
t->client_id_ = 0;
|
||||||
t->delete_on_disconnect_ = false;
|
t->delete_on_disconnect_ = false;
|
||||||
|
|
||||||
// AnimQueue initializes itself to a valid default state.
|
// AnimQueue initializes itself to a valid default state.
|
||||||
@@ -252,6 +252,7 @@ void World::tangible_delete(int64_t id) {
|
|||||||
if (iter == tangibles_.end()) {
|
if (iter == tangibles_.end()) {
|
||||||
return; // Nothing to delete.
|
return; // Nothing to delete.
|
||||||
}
|
}
|
||||||
|
Tangible *tan = iter->second.get();
|
||||||
|
|
||||||
// Fetch the lua side of the tangible.
|
// Fetch the lua side of the tangible.
|
||||||
LS.maketan(database, id);
|
LS.maketan(database, id);
|
||||||
@@ -266,6 +267,9 @@ void World::tangible_delete(int64_t id) {
|
|||||||
LS.rawset(metatab, "id", id);
|
LS.rawset(metatab, "id", id);
|
||||||
LS.rawset(metatab, "__metatable", false);
|
LS.rawset(metatab, "__metatable", false);
|
||||||
|
|
||||||
|
// If the tangible is in the connections table, remove it.
|
||||||
|
if (tan->client_id_ != 0) connections_.erase(tan->client_id_);
|
||||||
|
|
||||||
// Remove the C++ portion from the tangibles table.
|
// Remove the C++ portion from the tangibles table.
|
||||||
tangibles_.erase(iter);
|
tangibles_.erase(iter);
|
||||||
}
|
}
|
||||||
@@ -312,7 +316,7 @@ int64_t World::connection_create() {
|
|||||||
|
|
||||||
// Set the login flags.
|
// Set the login flags.
|
||||||
if (is_authoritative()) {
|
if (is_authoritative()) {
|
||||||
tan->is_controlled_ = true;
|
tan->client_id_ = id;
|
||||||
tan->delete_on_disconnect_ = true;
|
tan->delete_on_disconnect_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,11 +341,11 @@ void World::connection_delete(int64_t client_id) {
|
|||||||
auto iter = connections_.find(client_id);
|
auto iter = connections_.find(client_id);
|
||||||
if (iter == connections_.end()) return;
|
if (iter == connections_.end()) return;
|
||||||
int64_t actor_id = iter->second;
|
int64_t actor_id = iter->second;
|
||||||
connections_.erase(iter);
|
|
||||||
Tangible *tan = tangible_get(actor_id);
|
Tangible *tan = tangible_get(actor_id);
|
||||||
assert(tan != nullptr);
|
assert(tan != nullptr);
|
||||||
assert(tan->is_controlled_);
|
assert(tan->client_id_ == client_id);
|
||||||
tan->is_controlled_ = false;
|
connections_.erase(iter);
|
||||||
|
tan->client_id_ = 0;
|
||||||
if (tan->delete_on_disconnect_) {
|
if (tan->delete_on_disconnect_) {
|
||||||
util::dprintf("Deleted actor: %lld\n", actor_id);
|
util::dprintf("Deleted actor: %lld\n", actor_id);
|
||||||
tangible_delete(actor_id);
|
tangible_delete(actor_id);
|
||||||
@@ -354,32 +358,22 @@ int64_t World::connection_get_actor(int64_t client_id) const {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t World::connection_get_client(Tangible *actor) const {
|
|
||||||
if (!actor->is_controlled_) return 0;
|
|
||||||
for (const auto &pair : connections_) {
|
|
||||||
if (pair.second == actor->id()) return pair.first;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
eng::string World::connection_redirect(Tangible *actor1, Tangible *actor2) {
|
void World::connection_redirect(Tangible *actor1, Tangible *actor2) {
|
||||||
if (actor1 == actor2) return "";
|
if ((actor1 == nullptr) || (actor2 == nullptr) || (actor1 == actor2)) return;
|
||||||
|
|
||||||
if (!actor1->is_controlled_) {
|
int64_t client_id1 = actor1->client_id_;
|
||||||
return "actor1 is not logged in, cannot redirect";
|
if (client_id1 == 0) return;
|
||||||
}
|
|
||||||
|
|
||||||
// If neccessary, bump actor2. Do not implement delete-on-disconnect,
|
// If neccessary, bump actor2. Do not implement delete-on-disconnect,
|
||||||
// because actor2 isn't really "disconnected" yet.
|
// because actor2 isn't really "disconnected" yet.
|
||||||
if ((actor2 != nullptr) && (actor2->is_controlled_)) {
|
if ((actor2 != nullptr) && (actor2->client_id_ != 0)) {
|
||||||
int64_t client_id2 = connection_get_client(actor2);
|
connections_.erase(actor2->client_id_);
|
||||||
actor2->is_controlled_ = false;
|
actor2->client_id_ = 0;
|
||||||
connections_.erase(client_id2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t client_id1 = connection_get_client(actor1);
|
connections_.erase(actor1->client_id_);
|
||||||
actor1->is_controlled_ = false;
|
actor1->client_id_ = 0;
|
||||||
connections_.erase(client_id1);
|
|
||||||
|
|
||||||
if (actor1->delete_on_disconnect_) {
|
if (actor1->delete_on_disconnect_) {
|
||||||
tangible_delete(actor1->id());
|
tangible_delete(actor1->id());
|
||||||
@@ -387,10 +381,9 @@ eng::string World::connection_redirect(Tangible *actor1, Tangible *actor2) {
|
|||||||
|
|
||||||
if (actor2 != nullptr) {
|
if (actor2 != nullptr) {
|
||||||
connection_prepare(actor2);
|
connection_prepare(actor2);
|
||||||
actor2->is_controlled_ = true;
|
actor2->client_id_ = client_id1;
|
||||||
connections_[client_id1] = actor2->id();
|
connections_[client_id1] = actor2->id();
|
||||||
}
|
}
|
||||||
return "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void World::connection_close_all() {
|
void World::connection_close_all() {
|
||||||
|
|||||||
@@ -78,14 +78,13 @@ public:
|
|||||||
//
|
//
|
||||||
PrintBuffer print_buffer_;
|
PrintBuffer print_buffer_;
|
||||||
|
|
||||||
// Is Controlled Flag.
|
// Client ID
|
||||||
//
|
//
|
||||||
// This flag is set to true when a client is controlling this player.
|
// This variable is set to nonzero when a client is controlling this
|
||||||
// It gets set back to false when the client logs out or attaches
|
// player. If this is set, then the connections_ table contains a map
|
||||||
// to a different player. If this is set, then the connections_
|
// from a client ID to this actor.
|
||||||
// table contains a map from a client ID to this actor.
|
|
||||||
//
|
//
|
||||||
bool is_controlled_;
|
int64_t client_id_ = 0;
|
||||||
|
|
||||||
// Delete on Logout Flag.
|
// Delete on Logout Flag.
|
||||||
//
|
//
|
||||||
@@ -421,23 +420,17 @@ public:
|
|||||||
// Find out what actor the given client is controlling.
|
// Find out what actor the given client is controlling.
|
||||||
//
|
//
|
||||||
// This is used by the DrivenEngine to check if the given client has
|
// This is used by the DrivenEngine to check if the given client has
|
||||||
// changed actor, or if it has been forced to disconnect.
|
// changed actor, or if it has been forced to disconnect. Returns
|
||||||
|
// zero if the client is not controlling anything.
|
||||||
//
|
//
|
||||||
int64_t connection_get_actor(int64_t client_id) const;
|
int64_t connection_get_actor(int64_t client_id) const;
|
||||||
|
|
||||||
// Connection get client.
|
|
||||||
//
|
|
||||||
// Get the ID of the client that is controlling the specified actor.
|
|
||||||
//
|
|
||||||
int64_t connection_get_client(Tangible *tan) const;
|
|
||||||
|
|
||||||
// Connection redirection.
|
// Connection redirection.
|
||||||
//
|
//
|
||||||
// This is used by lua code to force changes in connection status.
|
// This is used by lua code to cause the client who is controlling
|
||||||
// It can be used to redirect a client, or disconnect a client
|
// actor1 to control actor2 instead.
|
||||||
// if actor2 == nullptr.
|
|
||||||
//
|
//
|
||||||
eng::string connection_redirect(Tangible *actor1, Tangible *actor2);
|
void connection_redirect(Tangible *actor1, Tangible *actor2);
|
||||||
|
|
||||||
// Close all connections.
|
// Close all connections.
|
||||||
//
|
//
|
||||||
|
|||||||
Reference in New Issue
Block a user