serverpermadeath

v1.0.0·Updated 2023-06-22

Server side only. Records deaths and bans characters when they die.

About this mod Author’s original text

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 servercharacters to have a hardcore server

install

prerequisite: have bepinex installed on server

drag serverpermadeath.dll into bepinex/plugins folder

restart server

code

public static SyncedList characterbans;

public static Dictionary timers = new Dictionary();

//initialize the synced list used for tracking bans

[HarmonyPatch(typeof(ZNet), "Awake")]

public static class awakepatch{

private static void Postfix()

{

characterbans = new SyncedList(Utils.GetSaveDataPath(FileHelpers.FileSource.Local) + "/permadeath.txt",

"List of dead players by steamid|charname - ONE per line - serverpermadeath mod");

}

}

[HarmonyPatch(typeof(ZNet), "CheckWhiteList")]

public static class CheckCharWhitelist

{

private static bool Prefix(ZNet __instance)

{

//runs every 5s

//check whitelist

if (__instance.m_peers!= null)

{

if (__instance.m_peers.Count > 0)

{

foreach (ZNetPeer znetPeer in __instance.m_peers.ToList())

{

if (znetPeer.IsReady() &&!znetPeer.m_characterID.IsNone())

{

string charName = znetPeer.m_playerName;

string id = znetPeer.m_socket.GetHostName();

string idandname = id + "|" + charName;

bool bannedalready = characterbans.Contains(idandname);

//they are banned, gtfo

if (bannedalready)

{

ZNet.instance.InternalKick(znetPeer);

}

else

{

//check if they're dead

ZDO zdo = __instance.m_zdoMan.GetZDO(znetPeer.m_characterID);

if (zdo!= null)

{

bool dead = zdo.GetBool("dead", false);

if (dead &&!TrippingPatches.timers.ContainsKey(idandname))

{

//tell everyone they are dead

ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "ChatMessage", new object

{

znetPeer.m_refPos,

2,

znetPeer.m_playerName,

znetPeer.m_playerName + " has been slain"

});

ZLog.Log(znetPeer.m_playerName + " DIED " + znetPeer.m_refPos.ToString());

//start a timer to kick them

TrippingPatches.timers.Add(idandname, 5);

}

}

}

}

}

}

}

//clean up the timers

foreach (string key in TrippingPatches.timers.Keys.ToList())

{

TrippingPatches.timers[key] = TrippingPatches.timers[key] - 1;

if (TrippingPatches.timers[key] < 0)

{

//add them to the banned list

characterbans.Add(key);

//remove the timer

TrippingPatches.timers.Remove(key);

}

}

return true;

}

}

Install & use Install: BepInEx plugin

  1. The archive from playbuff is the mod itself — usually a BepInEx plugin (a .dll or a plugin folder once unzipped).
  2. Recommended: use a community mod manager (such as r2modman) — pick this game, import the mod, and the manager sets up BepInEx and its dependencies for you.
  3. Manual route: install the BepInEx loader in the game folder, then drop the unzipped .dll or plugin folder into BepInEx/plugins/.
  4. Launch the game — the BepInEx console logs every plugin it loads; seeing this mod in the log means it is installed.

Mods with listed dependencies need those installed too, or they will not load. Options are usually changed in-game or in the plugin's config file. In multiplayer, the host and every client need the same mods installed.

Dependencies

Install these first, or the mod will not work:

denikson-BepInExPack_Valheim

File & checksum

Filename
serverpermadeath-1.0.0.zip
File size
17.9 KiB