
You are viewing a potentially older version of this package. View Latest Version
serverpermadeath
Server side only. Records deaths and bans characters when they die.serverpermadeath
this mod runs on the server only. The goal of this mod is to give server authority / no client mod solution to permadeath. We don't want to use the originally bannedlist.txt because that will ban a player all together. We want players to continue playing, they just can't use a character that has died.
new server textfile permadeath.txt
Server checks for dead players. if a player dies:
- adds steamid|charactername to permadeath.txt
- shout that player has died
- start a 30 sec timer giving them time to say goodbye
- kicks them, shows Banned popup
Server checks permadeath.txt and all players connected. if player|charactername is on list:
- kicks them, shows Banned popup
Combine this with serverfresh mod to attempt to have a hardcore server (game is easy to cheat if you know what you're doing).
install
prerequisite: have bepinex installed on server
drag serverpermadeath.dll into bepinex/plugins folder
restart server
code
public class ZNetPatches
{
public static SyncedList characterbans;
public static Dictionary<string,int> timers;
[HarmonyPatch(typeof(ZNet), "Awake")]
public static class ZNetAwakeBan
{
private static void Postfix(ZNet __instance)
{
characterbans = new SyncedList(Utils.GetSaveDataPath() + "/permadeath.txt",
"List of dead players by steamid|charname - ONE per line - serverpermadeath mod");
timers = new Dictionary<string, int>();
}
}
[HarmonyPatch(typeof(ZNet), "CheckWhiteList")]
public static class ZNetVariablePatch
{
private static void Postfix(ZNet __instance)
{
if (__instance.IsServer())
{
foreach (ZNetPeer znetPeer in __instance.m_peers)
{
if (znetPeer.IsReady() && !znetPeer.m_characterID.IsNone())
{
ZDO p = __instance.m_zdoMan.GetZDO(znetPeer.m_characterID);
if(p != null)
{
var dead = p.GetBool("dead");
var bannedalready = characterbans.Contains(znetPeer.m_socket.GetHostName() + "|" + znetPeer.m_playerName);
//we haven't seen the player dead yet
if(!timers.ContainsKey(znetPeer.m_playerName))
{
//check if they are dead
if (dead)
{
//send chat message on death
ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ChatMessage", new object[]
{
znetPeer.m_refPos,
2,
znetPeer.m_playerName,
znetPeer.m_playerName + " DIED"
});
//log in server log
ZLog.Log(znetPeer.m_playerName + " DIED");
//timer for kicking them
//allows them to say goodbye or rage
timers.Add(znetPeer.m_playerName, 6);
//add to permadeath list
characterbans.Add(znetPeer.m_socket.GetHostName() + "|" + znetPeer.m_playerName);
}
//if someone banned got into server get rid of them
if (bannedalready)
{
ZLog.Log(znetPeer.m_playerName + " permadeath user is already banned");
//send client banned popup (it disconnects them)
znetPeer.m_rpc.Invoke("Error", new object[]{8});
}
}
else
{
//player has been detected dead but we give them a little time to say goodbye
timers[znetPeer.m_playerName] = timers[znetPeer.m_playerName] - 1;
ZLog.Log("permadeath timer: " + timers[znetPeer.m_playerName]);
//timer expired, get rid of them
if (timers[znetPeer.m_playerName] < 1)
{
ZLog.Log(znetPeer.m_playerName + " permadeath timer expired " + timers[znetPeer.m_playerName]);
//remove from our permadeath timers
timers.Remove(znetPeer.m_playerName);
//send client banned popup (it disconnects them)
znetPeer.m_rpc.Invoke("Error", new object[] { 8 });
}
}
}
}
}
}
}
}
}

