private void ActivateServerToServerPortal(int ServerId, int PortalId, uint PlayerObjectId)
{
ALFA.Database Database = GetDatabase();
Database.ACR_IncrementStatistic("ACTIVATE_PORTAL");
lock (WorldManager)
{
GameServer Server = WorldManager.ReferenceServerById(ServerId, Database);
//
// Check our state first.
//
if (Server == null)
{
SendFeedbackError(PlayerObjectId, "Portal failed (destination server unknown).");
return;
}
if (Server.Online == false)
{
SendFeedbackError(PlayerObjectId, "Portal failed (destination server offline).");
return;
}
if ((WorldManager.Configuration.ProtectionLevel >= GameWorldConfiguration.MemberProtectionLevel.Quarantine) &&
(Database.ACR_GetIsMember(PlayerObjectId) == false))
{
SendFeedbackError(PlayerObjectId, "You don't have permission to use a server to server portal.");
return;
}
//
// If we're a DM, there is no server vault character to
// transfer. Save any database state and just start things
// off.
//
if (GetIsDM(PlayerObjectId) != FALSE)
{
SendMessageToPC(PlayerObjectId, "DM portals are not supported. You must manually log out and connect to the desired server.");
/*
SendMessageToPC(PlayerObjectId, "Initiating DM portal...");
GetDatabase().ACR_PCSave(PlayerObjectId, true, true);
GetDatabase().ACR_FlushQueryQueue(PlayerObjectId);
ActivatePortal(
PlayerObjectId,
String.Format("{0}:{1}", Server.ServerHostname, Server.ServerPort),
WorldManager.Configuration.PlayerPassword,
"",
TRUE);
*/
return;
}
if ((GetDatabase().ACR_GetPCLocalFlags(PlayerObjectId) & ALFA.Database.ACR_PC_LOCAL_FLAG_PORTAL_IN_PROGRESS) != 0)
{
SendMessageToPC(PlayerObjectId, "A portal attempt is already in progress.");
return;
}
//
// Disable actions on the player while we are waiting for them
// to transfer. This is intended to help prevent a player from
// causing the canonical save to miss something important, like
// an item dropped on the ground.
//
int WasCommandable = GetCommandable(PlayerObjectId);
SetCommandable(FALSE, PlayerObjectId);
if (IsInConversation(PlayerObjectId) != FALSE)
AssignCommand(PlayerObjectId, delegate() { ActionPauseConversation(); });
//
// Set up a fallback DelayCommand continuation set to send a
// failure error to the player and exit the portal loop.
//
AssignCommand(PlayerObjectId, delegate()
{
DelayCommand(60.0f, delegate()
{
//
// Let the player know that we failed.
//
SendMessageToPC(PlayerObjectId, "Portal failed (timed out).");
if ((GetDatabase().ACR_GetPCLocalFlags(PlayerObjectId) & ALFA.Database.ACR_PC_LOCAL_FLAG_PORTAL_COMMITTED) == 0)
{
//
// We are aborting the portal before we are fully
// committed. Unwind back from the non-commandable
// state and tell the player that they can retry if
// desired.
//
GetDatabase().ACR_SetPCLocalFlags(
PlayerObjectId,
GetDatabase().ACR_GetPCLocalFlags(PlayerObjectId) & ~(ALFA.Database.ACR_PC_LOCAL_FLAG_PORTAL_IN_PROGRESS));
SendMessageToPC(PlayerObjectId, "You may re-try the portal if desired. Contact the tech team if the issue persists.");
if (GetCommandable(PlayerObjectId) == FALSE)
SetCommandable(WasCommandable, PlayerObjectId);
if (IsInConversation(PlayerObjectId) != FALSE)
ActionResumeConversation();
Database.ACR_IncrementStatistic("PORTAL_FAILED_UNCOMMITTED");
}
else
{
SendMessageToPC(PlayerObjectId, "Please reconnect.");
Database.ACR_IncrementStatistic("PORTAL_FAILED_COMMITTED");
//
// We have already committed to portaling, as we
// have sent the portal request. There's no way to
// know if the client is still waiting or gave up,
// so the only way to recover for certain is to
// disconnect the player.
//
DelayCommand(3.0f, delegate() { BootPC(PlayerObjectId); });
}
});
});
//
// Initiate a full player save. This must be done BEFORE we
// enter into PortalStatusCheck, so that the export request is
// acted on beforehand and the character goes into the queue
// for remote transfer.
//
GetDatabase().ACR_PCSave(PlayerObjectId, true, true);
//
// Enlist the player in periodic status updates so that they
// know what's happening. This also checks whether the vault
// transfer has finished for the ACR_PCSave above, so that we
// can complete the transfer transaction entirely.
//
GetDatabase().ACR_SetPCLocalFlags(
PlayerObjectId,
GetDatabase().ACR_GetPCLocalFlags(PlayerObjectId) | ALFA.Database.ACR_PC_LOCAL_FLAG_PORTAL_IN_PROGRESS);
AssignCommand(PlayerObjectId, delegate()
{
PortalStatusCheck(PlayerObjectId, Server);
});
}
}