serverpermadeath
Server side only. Records deaths and bans characters when they die.
Date uploaded | 3 years ago |
Version | 0.0.1 |
Download link | 1010101110-serverpermadeath-0.0.1.zip |
Downloads | 501 |
Dependency string | 1010101110-serverpermadeath-0.0.1 |
This mod requires the following mods to function
denikson-BepInExPack_Valheim
BepInEx pack for Valheim. Preconfigured and includes unstripped Unity DLLs.
Preferred version: 5.4.2105README
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 });
}
}
}
}
}
}
}
}
}