123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788 |
- //! int time of the logout end
- //: string uid of the player
- typedef Param2<int, string> LogoutInfo;
- class MissionServer extends MissionBase
- {
- ref array<Man> m_Players;
- ref array<ref CorpseData> m_DeadPlayersArray;
- ref map<PlayerBase, ref LogoutInfo> m_LogoutPlayers;
- ref map<PlayerBase, ref LogoutInfo> m_NewLogoutPlayers;
- ref RainProcurementHandler m_RainProcHandler;
- const int SCHEDULER_PLAYERS_PER_TICK = 5;
- int m_currentPlayer;
- int m_RespawnMode;
-
- // -----------------------
- // ARTILLERY SOUNDS SETUP
- // -----------------------
- private float m_ArtyBarrageTimer = 0; // This is not to be edited in Init.c this is just to increment time
-
- // Variables to be modified in Init.c
- protected bool m_PlayArty = false; // Toggle if Off map artillery sounds are played
- protected float m_ArtyDelay = 0; // Set how much time there is between two barrages (in seconds)
- protected int m_MinSimultaneousStrikes = 0; // The MIN of simultaneous shots on the map (Will be clamped between 1 and max shots)
- protected int m_MaxSimultaneousStrikes = 0; // The MAX of simultaneous shots on the map (Will be clamped between 1 and max amount of coords)
- protected ref array<vector> m_FiringPos; // Where we should fire from. On Init set the relevant data
-
- //All Chernarus firing coordinates
- protected const ref array<vector> CHERNARUS_STRIKE_POS =
- {
- "-500.00 165.00 5231.69",
- "-500.00 300.00 9934.41",
- "10406.86 192.00 15860.00",
- "4811.75 370.00 15860.00",
- "-500.00 453.00 15860.00"
- };
-
- //All livonia firing coordinates
- protected const ref array<vector> LIVONIA_STRIKE_POS =
- {
- "7440.00 417.00 -500.00",
- "-500.00 276.00 5473.00",
- "-500.00 265.00 9852.00",
- "4953.00 240.00 13300.00",
- "9620.00 188.00 13300.00",
- "13300.00 204.00 10322.00",
- "13300.00 288.00 6204.00",
- "13300.00 296.00 -500.00"
- };
- // -----------------------
- // END OF ARTILLERY SETUP
- // -----------------------
-
- PlayerBase m_player;
- MissionBase m_mission;
-
- void MissionServer()
- {
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(this.UpdatePlayersStats, 30000, true);
- m_DeadPlayersArray = new array<ref CorpseData>;
- UpdatePlayersStats();
- m_Players = new array<Man>;
-
- m_LogoutPlayers = new map<PlayerBase, ref LogoutInfo>;
- m_NewLogoutPlayers = new map<PlayerBase, ref LogoutInfo>;
- m_RainProcHandler = new RainProcurementHandler(this);
- m_ActiveRefresherLocations = new array<vector>();
- }
-
- void ~MissionServer()
- {
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).Remove(this.UpdatePlayersStats);
- }
-
- override void OnInit()
- {
- super.OnInit();
- CfgGameplayHandler.LoadData();
- PlayerSpawnHandler.LoadData();
- CfgPlayerRestrictedAreaHandler.LoadData();
- UndergroundAreaLoader.SpawnAllTriggerCarriers();
- //Either pass consts in Init.c or insert all desired coords (or do both ;))
- m_FiringPos = new array<vector>();
- }
-
- override void OnMissionStart()
- {
- super.OnMissionStart();
-
- // We will load the Effect areas on Default mission start
- EffectAreaLoader.CreateZones();
- }
-
- override void OnUpdate(float timeslice)
- {
- UpdateDummyScheduler();
- TickScheduler(timeslice);
- UpdateLogoutPlayers();
- m_WorldData.UpdateBaseEnvTemperature(timeslice); // re-calculate base enviro temperature
- m_RainProcHandler.Update(timeslice);
-
- RandomArtillery(timeslice);
-
- super.OnUpdate(timeslice);
- }
-
- override void OnGameplayDataHandlerLoad()
- {
- m_RespawnMode = CfgGameplayHandler.GetDisableRespawnDialog();
- GetGame().SetDebugMonitorEnabled(GetGame().ServerConfigGetInt("enableDebugMonitor"));
-
- InitialiseWorldData();
- }
-
-
- void RandomArtillery(float deltaTime)
- {
- // ARTY barrage
- if (m_PlayArty)
- {
- // We only perform timer checks and increments if we enabled the artillery barrage
- if (m_ArtyBarrageTimer > m_ArtyDelay)
- {
- //We clamp to guarantee 1 and never have multiple shots on same pos, even in case of entry error
- m_MaxSimultaneousStrikes = Math.Clamp(m_MaxSimultaneousStrikes, 1, m_FiringPos.Count());
- m_MinSimultaneousStrikes = Math.Clamp(m_MinSimultaneousStrikes, 1, m_MaxSimultaneousStrikes);
-
- // Variables to be used in this scope
- int randPos; // Select random position
- Param1<vector> pos; // The value to be sent through RPC
- array<ref Param> params; // The RPC params
-
- if (m_MaxSimultaneousStrikes == 1)
- {
- // We only have one set of coordinates to send
- randPos = Math.RandomIntInclusive(0, m_FiringPos.Count() - 1);
- pos = new Param1<vector>(m_FiringPos[randPos]);
- params = new array<ref Param>;
- params.Insert(pos);
- GetGame().RPC(null, ERPCs.RPC_SOUND_ARTILLERY, params, true);
- }
- else
- {
- //We will do some extra steps to
- /*
- 1. Send multiple coords (Send one RPC per coord set)
- 2. Ensure we don't have duplicates
- */
- array<int> usedIndices = new array<int>; // Will store all previusly fired upon indices
-
- // We determine how many positions fire between MIN and MAX
- int randFireNb = Math.RandomIntInclusive(m_MinSimultaneousStrikes, m_MaxSimultaneousStrikes);
- for (int i = 0; i < randFireNb; i++)
- {
- randPos = Math.RandomIntInclusive(0, m_FiringPos.Count() - 1);
-
- if (usedIndices.Count() <= 0 || usedIndices.Find(randPos) < 0) //We do not find the index or array is empty
- {
- // We prepare to send the message
- pos = new Param1<vector>(m_FiringPos[randPos]);
- params = new array<ref Param>;
-
- // We send the message with this set of coords
- params.Insert(pos);
- GetGame().RPC(null, ERPCs.RPC_SOUND_ARTILLERY, params, true);
-
- // We store the last used value
- usedIndices.Insert(randPos);
- }
- }
- }
-
- // Reset timer for new loop
- m_ArtyBarrageTimer = 0.0;
- }
-
- m_ArtyBarrageTimer += deltaTime;
- }
- }
- override bool IsServer()
- {
- return true;
- }
-
- override bool IsPlayerDisconnecting(Man player)
- {
- return (m_LogoutPlayers && m_LogoutPlayers.Contains(PlayerBase.Cast(player))) || (m_NewLogoutPlayers && m_NewLogoutPlayers.Contains(PlayerBase.Cast(player)));
- }
-
- void UpdatePlayersStats()
- {
- PluginLifespan moduleLifespan;
- Class.CastTo(moduleLifespan, GetPlugin(PluginLifespan));
- array<Man> players = new array<Man>();
- GetGame().GetPlayers(players);
-
- foreach (Man man : players)
- {
- PlayerBase player;
- if (Class.CastTo(player, man))
- {
- player.StatUpdateByTime(AnalyticsManagerServer.STAT_PLAYTIME);
- player.StatUpdateByPosition(AnalyticsManagerServer.STAT_DISTANCE);
- moduleLifespan.UpdateLifespan(player);
- }
- }
-
- UpdateCorpseStatesServer();
- }
-
- protected void AddNewPlayerLogout(PlayerBase player, notnull LogoutInfo info)
- {
- m_LogoutPlayers.Insert(player, info);
- m_NewLogoutPlayers.Remove(player);
- }
-
- // check if logout finished for some players
- void UpdateLogoutPlayers()
- {
- for (int i = 0; i < m_LogoutPlayers.Count();)
- {
- LogoutInfo info = m_LogoutPlayers.GetElement(i);
-
- if (GetGame().GetTime() >= info.param1)
- {
- PlayerIdentity identity;
- PlayerBase player = m_LogoutPlayers.GetKey(i);
- if (player)
- {
- identity = player.GetIdentity();
- m_LogoutPlayers.Remove(player);
- }
- else
- {
- m_LogoutPlayers.RemoveElement(i);
- }
-
- // disable reconnecting to old char
- // GetGame().RemoveFromReconnectCache(info.param2);
-
- PlayerDisconnected(player, identity, info.param2);
- }
- else
- {
- ++i;
- }
- }
- }
-
- override void OnEvent(EventType eventTypeId, Param params)
- {
- PlayerIdentity identity;
- PlayerBase player;
- int counter = 0;
-
- switch (eventTypeId)
- {
- case ClientPrepareEventTypeID:
- ClientPrepareEventParams clientPrepareParams;
- Class.CastTo(clientPrepareParams, params);
- CfgGameplayHandler.SyncDataSendEx(clientPrepareParams.param1);
- UndergroundAreaLoader.SyncDataSend(clientPrepareParams.param1);
- CfgPlayerRestrictedAreaHandler.SyncDataSend(clientPrepareParams.param1);
- OnClientPrepareEvent(clientPrepareParams.param1, clientPrepareParams.param2, clientPrepareParams.param3, clientPrepareParams.param4, clientPrepareParams.param5);
- break;
- case ClientNewEventTypeID:
- ClientNewEventParams newParams;
- Class.CastTo(newParams, params);
- player = OnClientNewEvent(newParams.param1, newParams.param2, newParams.param3);
- if (!player)
- {
- Debug.Log("ClientNewEvent: Player is empty");
- return;
- }
- identity = newParams.param1;
- InvokeOnConnect(player,identity);
- SyncEvents.SendPlayerList();
-
- ControlPersonalLight(player);
- SyncGlobalLighting(player);
-
- break;
-
- case ClientReadyEventTypeID:
- ClientReadyEventParams readyParams;
- Class.CastTo(readyParams, params);
- identity = readyParams.param1;
- Class.CastTo(player, readyParams.param2);
- if (!player)
- {
- Debug.Log("ClientReadyEvent: Player is empty");
- return;
- }
-
- OnClientReadyEvent(identity, player);
- InvokeOnConnect(player, identity);
- // Send list of players at all clients
- SyncEvents.SendPlayerList();
- ControlPersonalLight(player);
- SyncGlobalLighting(player);
- break;
-
- case ClientRespawnEventTypeID:
- ClientRespawnEventParams respawnParams;
- Class.CastTo(respawnParams, params);
- identity = respawnParams.param1;
- Class.CastTo(player, respawnParams.param2);
- if (!player)
- {
- Debug.Log("ClientRespawnEvent: Player is empty");
- return;
- }
-
- OnClientRespawnEvent(identity, player);
- break;
-
- case ClientReconnectEventTypeID:
- ClientReconnectEventParams reconnectParams;
- Class.CastTo(reconnectParams, params);
-
- identity = reconnectParams.param1;
- Class.CastTo(player, reconnectParams.param2);
- if (!player)
- {
- Debug.Log("ClientReconnectEvent: Player is empty");
- return;
- }
-
- OnClientReconnectEvent(identity, player);
- break;
-
- case ClientDisconnectedEventTypeID:
- ClientDisconnectedEventParams discoParams;
- Class.CastTo(discoParams, params);
-
- identity = discoParams.param1;
- Class.CastTo(player, discoParams.param2);
- int logoutTime = discoParams.param3;
- bool authFailed = discoParams.param4;
- if (!player)
- {
- Debug.Log("ClientDisconnectenEvent: Player is empty");
- return;
- }
-
- OnClientDisconnectedEvent(identity, player, logoutTime, authFailed);
- break;
-
- case LogoutCancelEventTypeID:
- LogoutCancelEventParams logoutCancelParams;
-
- Class.CastTo(logoutCancelParams, params);
- Class.CastTo(player, logoutCancelParams.param1);
- identity = player.GetIdentity();
- if (identity)
- {
- // disable reconnecting to old char
- // GetGame().RemoveFromReconnectCache(identity.GetId());
- Print("[Logout]: Player " + identity.GetId() + " cancelled");
- }
- else
- {
- Print("[Logout]: Player cancelled");
- }
- m_LogoutPlayers.Remove(player);
- m_NewLogoutPlayers.Remove(player);
- break;
- }
- }
-
- void InvokeOnConnect(PlayerBase player, PlayerIdentity identity)
- {
- Debug.Log("InvokeOnConnect:"+this.ToString(),"Connect");
- if (player)
- player.OnConnect();
- }
- void InvokeOnDisconnect(PlayerBase player)
- {
- Debug.Log("InvokeOnDisconnect:"+this.ToString(),"Connect");
- if (player)
- player.OnDisconnect();
- }
- void OnClientPrepareEvent(PlayerIdentity identity, out bool useDB, out vector pos, out float yaw, out int preloadTimeout)
- {
- if (GetHive())
- {
- // use character from database
- useDB = true;
- }
- else
- {
- // use following data without database
- useDB = false;
- pos = "1189.3 0.0 5392.48";
- yaw = 0;
- }
- }
-
- // Enables/Disables personal light on the given player.
- void ControlPersonalLight(PlayerBase player)
- {
- if (player)
- {
- bool is_personal_light = ! GetGame().ServerConfigGetInt("disablePersonalLight");
- Param1<bool> personal_light_toggle = new Param1<bool>(is_personal_light);
- GetGame().RPCSingleParam(player, ERPCs.RPC_TOGGLE_PERSONAL_LIGHT, personal_light_toggle, true, player.GetIdentity());
- }
- else
- {
- Error("Error! Player was not initialized at the right time. Thus cannot send RPC command to enable or disable personal light!");
- }
- }
-
- // syncs global lighting setup from the server (lightingConfig server config parameter)
- void SyncGlobalLighting(PlayerBase player)
- {
- if (player)
- {
- int lightingID = GetGame().ServerConfigGetInt("lightingConfig");
- Param1<int> lightID = new Param1<int>(lightingID);
- GetGame().RPCSingleParam(player, ERPCs.RPC_SEND_LIGHTING_SETUP, lightID, true, player.GetIdentity());
- }
- }
-
- //! returns whether received data is valid, ctx can be filled on client in StoreLoginData()
- bool ProcessLoginData(ParamsReadContext ctx)
- {
- //creates temporary server-side structure for handling default character spawn
- return GetGame().GetMenuDefaultCharacterData(false).DeserializeCharacterData(ctx);
- }
-
- //
- PlayerBase CreateCharacter(PlayerIdentity identity, vector pos, ParamsReadContext ctx, string characterName)
- {
- Entity playerEnt;
- playerEnt = GetGame().CreatePlayer(identity, characterName, pos, 0, "NONE");//Creates random player
- Class.CastTo(m_player, playerEnt);
-
- GetGame().SelectPlayer(identity, m_player);
-
- return m_player;
- }
-
- //! Spawns character equip from received data. Checks validity against config, randomizes if invalid value and config array not empty.
- void EquipCharacter(MenuDefaultCharacterData char_data)
- {
- int slot_ID;
- string attachment_type;
- for (int i = 0; i < DefaultCharacterCreationMethods.GetAttachmentSlotsArray().Count(); i++)
- {
- slot_ID = DefaultCharacterCreationMethods.GetAttachmentSlotsArray().Get(i);
- attachment_type = "";
- if (m_RespawnMode != GameConstants.RESPAWN_MODE_CUSTOM || !char_data.GetAttachmentMap().Find(slot_ID,attachment_type) || !VerifyAttachmentType(slot_ID,attachment_type)) //todo insert verification fn here
- {
- //randomize
- if (DefaultCharacterCreationMethods.GetConfigArrayCountFromSlotID(slot_ID) > 0)
- {
- attachment_type = DefaultCharacterCreationMethods.GetConfigAttachmentTypes(slot_ID).GetRandomElement();
- }
- else //undefined, moving on
- continue;
- }
-
- if (attachment_type != "")
- {
- m_player.GetInventory().CreateAttachmentEx(attachment_type,slot_ID);
- }
- }
-
- StartingEquipSetup(m_player, true);
- }
-
- //! can be overriden to manually set up starting equip. 'clothesChosen' is legacy parameter, does nothing.
- void StartingEquipSetup(PlayerBase player, bool clothesChosen)
- {
- }
-
- bool VerifyAttachmentType(int slot_ID, string attachment_type)
- {
- return DefaultCharacterCreationMethods.GetConfigAttachmentTypes(slot_ID).Find(attachment_type) > -1;
- }
-
- PlayerBase OnClientNewEvent(PlayerIdentity identity, vector pos, ParamsReadContext ctx)
- {
- string characterType = GetGame().CreateRandomPlayer();
- bool generateRandomEquip = false;
-
- // get login data for new character
- if (ProcessLoginData(ctx) && (m_RespawnMode == GameConstants.RESPAWN_MODE_CUSTOM) && !GetGame().GetMenuDefaultCharacterData(false).IsRandomCharacterForced())
- {
- if (GetGame().ListAvailableCharacters().Find(GetGame().GetMenuDefaultCharacterData().GetCharacterType()) > -1)
- characterType = GetGame().GetMenuDefaultCharacterData().GetCharacterType();
- }
- else
- {
- generateRandomEquip = true;
- }
-
- if (PlayerSpawnHandler.IsInitialized())
- {
- PlayerSpawnPreset presetData = PlayerSpawnHandler.GetRandomCharacterPreset();
- if (presetData && presetData.IsValid())
- {
- string presetCharType = presetData.GetRandomCharacterType();
- if (presetCharType == string.Empty)
- presetCharType = characterType;
- if (CreateCharacter(identity, pos, ctx, presetCharType) != null)
- {
- PlayerSpawnHandler.ProcessEquipmentData(m_player,presetData);
- return m_player;
- }
- else
- {
- ErrorEx("Failed to create character from type: " + presetCharType + ", using default spawning method");
- }
- }
- else
- {
- ErrorEx("Failed to load PlayerSpawnPreset data properly, using default spawning method");
- }
- }
-
- if (CreateCharacter(identity, pos, ctx, characterType))
- {
- if (generateRandomEquip)
- GetGame().GetMenuDefaultCharacterData().GenerateRandomEquip();
- EquipCharacter(GetGame().GetMenuDefaultCharacterData());
- }
-
- return m_player;
- }
-
- void OnClientReadyEvent(PlayerIdentity identity, PlayerBase player)
- {
- GetGame().SelectPlayer(identity, player);
-
- #ifdef DIAG_DEVELOPER
- if (FeatureTimeAccel.m_CurrentTimeAccel)
- {
- GetGame().RPCSingleParam(player, ERPCs.DIAG_TIMEACCEL_CLIENT_SYNC, FeatureTimeAccel.m_CurrentTimeAccel, true, identity);
- }
- #endif
- }
-
- void OnClientRespawnEvent(PlayerIdentity identity, PlayerBase player)
- {
- if (player)
- {
- if (player.IsUnconscious() || player.IsRestrained())
- {
- PluginAdminLog adm = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
- adm.PlayerKilledByRespawn(player);
-
- // kill character
- player.SetHealth("", "", 0.0);
- }
- }
-
- #ifdef DIAG_DEVELOPER
- if (FeatureTimeAccel.m_CurrentTimeAccel)
- {
- GetGame().RPCSingleParam(player, ERPCs.DIAG_TIMEACCEL_CLIENT_SYNC, FeatureTimeAccel.m_CurrentTimeAccel, true, identity);
- }
- #endif
- }
-
- void OnClientReconnectEvent(PlayerIdentity identity, PlayerBase player)
- {
- if (player)
- {
- player.OnReconnect();
- }
- }
-
- void OnClientDisconnectedEvent(PlayerIdentity identity, PlayerBase player, int logoutTime, bool authFailed)
- {
- bool disconnectNow = true;
-
- // TODO: get out of vehicle
- // using database and no saving if authorization failed
- if (GetHive() && !authFailed)
- {
- if (player.IsAlive())
- {
- if (!m_LogoutPlayers.Contains(player) && !m_NewLogoutPlayers.Contains(player))
- {
- Print("[Logout]: New player " + identity.GetId() + " with logout time " + logoutTime.ToString());
-
- // send statistics to client
- player.StatSyncToClient();
-
- // inform client about logout time
- GetGame().SendLogoutTime(player, logoutTime);
-
- // wait for some time before logout and save
- LogoutInfo params = new LogoutInfo(GetGame().GetTime() + logoutTime * 1000, identity.GetId());
-
- m_NewLogoutPlayers.Insert(player, params);
- GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(AddNewPlayerLogout, 0, false, player, params);
-
- // allow reconnecting to old char only if not in cars, od ladders etc. as they cannot be properly synchronized for reconnect
- //if (!player.GetCommand_Vehicle() && !player.GetCommand_Ladder())
- //{
- // GetGame().AddToReconnectCache(identity);
- //}
- // wait until logout timer runs out
- disconnectNow = false;
- }
- return;
- }
- }
-
- if (disconnectNow)
- {
- Print("[Logout]: New player " + identity.GetId() + " with instant logout");
-
- // inform client about instant logout
- GetGame().SendLogoutTime(player, 0);
-
- PlayerDisconnected(player, identity, identity.GetId());
- }
- }
- void PlayerDisconnected(PlayerBase player, PlayerIdentity identity, string uid)
- {
- // Note: At this point, identity can be already deleted
- if (!player)
- {
- Print("[Logout]: Skipping player " + uid + ", already removed");
- return;
- }
-
- // disable reconnecting to old char
- //GetGame().RemoveFromReconnectCache(uid);
- // now player can't cancel logout anymore, so call everything needed upon disconnect
- InvokeOnDisconnect(player);
- Print("[Logout]: Player " + uid + " finished");
- if (GetHive())
- {
- // save player
- player.Save();
-
- // unlock player in DB
- GetHive().CharacterExit(player);
- }
-
- // handle player's existing char in the world
- player.ReleaseNetworkControls();
- HandleBody(player);
-
- // remove player from server
- GetGame().DisconnectPlayer(identity, uid);
- // Send list of players at all clients
- GetGame().GetCallQueue(CALL_CATEGORY_SYSTEM).CallLater(SyncEvents.SendPlayerList, 1000);
- }
-
- bool ShouldPlayerBeKilled(PlayerBase player)
- {
- if (player.IsUnconscious() || player.IsRestrained())
- {
- switch (player.GetKickOffReason())
- {
- case EClientKicked.SERVER_EXIT:
- return false;
- case EClientKicked.KICK_ALL_ADMIN:
- return false;
- case EClientKicked.KICK_ALL_SERVER:
- return false;
- case EClientKicked.SERVER_SHUTDOWN:
- return false;
- default:
- return true;
- }
- }
-
- return false;
- }
-
- void HandleBody(PlayerBase player)
- {
- if (player.IsAlive())
- {
- if (ShouldPlayerBeKilled(player))
- {
- PluginAdminLog adm = PluginAdminLog.Cast(GetPlugin(PluginAdminLog));
- adm.PlayerKilledByDisconnect(player);
-
- player.SetHealth("", "", 0.0);//kill
- }
- else
- {
- player.Delete();// remove the body
- }
- }
- }
-
- void TickScheduler(float timeslice)
- {
- GetGame().GetWorld().GetPlayerList(m_Players);
- int players_count = m_Players.Count();
- int tick_count_max = Math.Min(players_count, SCHEDULER_PLAYERS_PER_TICK);
-
- for (int i = 0; i < tick_count_max; i++)
- {
- if (m_currentPlayer >= players_count)
- {
- m_currentPlayer = 0;
- }
-
- PlayerBase currentPlayer = PlayerBase.Cast(m_Players.Get(m_currentPlayer));
-
- if (currentPlayer)
- currentPlayer.OnTick();
- m_currentPlayer++;
- }
- }
-
- //--------------------------------------------------
- override bool InsertCorpse(Man player)
- {
- CorpseData corpse_data = new CorpseData(PlayerBase.Cast(player),GetGame().GetTime());
- return m_DeadPlayersArray.Insert(corpse_data) >= 0;
- }
-
- void UpdateCorpseStatesServer()
- {
- if (m_DeadPlayersArray.Count() == 0)//nothing to process, abort
- return;
- int current_time = GetGame().GetTime();
- array<int> invalid_corpses = new array<int>;
- CorpseData corpse_data;
-
- for (int i = 0; i < m_DeadPlayersArray.Count(); i++)
- {
- corpse_data = m_DeadPlayersArray.Get(i);
- if (!corpse_data || (corpse_data && (!corpse_data.m_Player || !corpse_data.m_bUpdate)))
- {
- invalid_corpses.Insert(i);
- }
- else if (corpse_data.m_bUpdate && current_time - corpse_data.m_iLastUpdateTime >= 30000)
- {
- corpse_data.UpdateCorpseState();
- corpse_data.m_iLastUpdateTime = current_time;
- }
- }
-
- //cleanup
- if (invalid_corpses.Count() > 0)
- {
- for (i = invalid_corpses.Count() - 1; i > -1; i--)
- {
- m_DeadPlayersArray.Remove(invalid_corpses.Get(i));
- }
- }
- }
- //--------------------------------------------------
-
- override void SyncRespawnModeInfo(PlayerIdentity identity)
- {
- ScriptRPC rpc = new ScriptRPC();
- rpc.Write(m_RespawnMode);
- rpc.Send(null, ERPCs.RPC_SERVER_RESPAWN_MODE, true, identity);
- }
-
- override RainProcurementHandler GetRainProcurementHandler()
- {
- return m_RainProcHandler;
- }
-
- override array<vector> GetActiveRefresherLocations()
- {
- return m_ActiveRefresherLocations;
- }
-
- //! DEPRECATED
- PluginAdditionalInfo m_moduleDefaultCharacter;
- }
|