Jump to content

dwarfmaster1974

Members
  • Posts

    89
  • Joined

  • Last visited

Everything posted by dwarfmaster1974

  1. I haven't found the time to play for a very long time and today I wanted to try the game again. In the meantime, however, I am no longer using Windows, but Linux (Ubuntu), which leads me to the same problem that has already been described here in great detail. Whenever I do anything with the controller, I get an error message that completely prevents me from continuing to play. DllNotFoundException: MouseLib assembly:<unknown assembly> type:<unknown type> member:(null) at (wrapper managed-to-native) MouseLib+MouseWrapper._GetGlobalMousePosition(int&,int&) at MouseLib+MouseWrapper.GetGlobalMousePosition () [0x00018] in <346e2f36c7a746908cb867e5fba1e7e8>:0 at MouseLib.GetGlobalMousePosition () [0x00000] in <346e2f36c7a746908cb867e5fba1e7e8>:0 at MouseLib.setCursorPositionInternal (System.Int32 xPos, System.Int32 yPos, System.Boolean relativeToWindow) [0x00009] in <346e2f36c7a746908cb867e5fba1e7e8>:0 at MouseLib.SetCursorPosition (System.Int32 xPos, System.Int32 yPos) [0x00000] in <346e2f36c7a746908cb867e5fba1e7e8>:0 at FlexibleCursor.SetScreenPosition (UnityEngine.Vector2 _newPosition) [0x00000] in <fc151fcabca749c7ab155658dacb12b4>:0 at FlexibleCursor.SetScreenPosition (System.Single _x, System.Single _y) [0x00008] in <fc151fcabca749c7ab155658dacb12b4>:0 at FlexibleCursor.HandleControllerInput () [0x000e7] in <fc151fcabca749c7ab155658dacb12b4>:0 at FlexibleCursor.Update () [0x00034] in <fc151fcabca749c7ab155658dacb12b4>:0 That's a pity, of course, as I've only ever hunted zombies with the controller. So I would also be very happy about a solution.
  2. Hi @Deadsimon, I also searched for any docs, but I haven't found a full one. So I tried a little around and wrote it down in this thread/post: Maybe this can help you.
  3. Howdy @Robcat DeGaul, thank you for your input. Regarding the color, the solution is quite simple. In the file `/Config/XUi/windows.xml` you will find the following 2 lines: <text_outline depth="1" x="49" y="-49" distance="2" size="50,50" text_color="255,255,255" shadow_color="0,0,0" text="●" font_size="3"/> <text_outline depth="1" x="30" y="-33" distance="2" size="50,50" text_color="255,255,255" shadow_color="0,0,0" text="β—‹" font_size="40"/> The first line is the dot in the middle, and the second line is the surrounding circle. There, you can change the attribute `text_color` to your favorite color. To find the appropriate color code I always use this page here: https://encycolorpedia.de/, but if it should be the color red it should look like this: `text_color="255,0,0"` and for example for lime it would be `text_color="0,255,0"`. As for the exchange of the characters, you have to try a little bit. The respective attribute `text` exchanges the content from dot to e.g. '+' and with `font_size` you can change the size in pixels. Maybe you have to adjust the attributes x and y a little bit. Of course, you can also do something like `text="( )"`, there are no restrictions. I hope this helps you
  4. Hi @Pennywise86, the idea is great, and I come to it also immediately many other ideas, but there is also a little bit of criticism. You just add the zombies, items and buff and do not delete existing, which leads to errors at the start because, for example, `zombieMoe` is double. There are 2 possibilities from my point of view. Examples: 1. delete before adding: <remove xpath="/entityclasses/entity_class[@name='zombieMoe']"/> After that, add like you did it now. 2. set <set xpath="/entityclasses/entity_class[@name='zombieMoe']"> <property .../> </set>
  5. Hallo zusammen, I just added the missing icons and also the name of the icon. This makes the whole thing a little more usable. Download can still be found here: https://github.com/OmitLeChuck/ui_game_symbols
  6. Hi @HYper, after a little research, I think I found it. In the file `windows.xml` make the following change: `<rect>` becomes `<rect controller="HUDStatBar" stat_type="VehicleHealth" visible="{#!statvisible}">` This means that when a vehicle health is displayed, the crosshair is hidden and this is only displayed when you are sitting and driving on the vehicle I have also customized this on Github. So a new download would do as well. Best regards
  7. Hi @HYper, Thanks for your feedback. I honestly didn't think about the vehicles at all. I would have to look in detail if there are variables that allow to hide things in vehicle mode. Best regards
  8. Hi all, this is actually more an attempt or a suggestion than a really finished mod. Because in principle I find (especially with a 4K screen) the target crosses in the game much too small and sometimes barely visible. May of course be due to my advanced age, but especially with larger hordes, I just do not see the thing. For my part, of course, I would like to see here possibly reignite a discussion that has already been held 1000 times, that the game (like so many other games) offers a configuration for something like this. Anyway. Here is the download: github.com - dwarfmaster-crosshair Solved is in principle quite simple. The old target cross is switched off as far as it goes, and the new one is just a correctly positioned character at the end
  9. Hello all, here is a mod, which is not an extension of the game, but is intended as a help for the admins / modders among you. It does nothing else than display all icons of the game. Here is the download: https://github.com/OmitLeChuck/ui_game_symbols To open the window just type the command `xui open ui_game_symbols`. Have fun with it
  10. A block that can be crafted by the player (very expensive) and provides just about all the resources you need. However, these resources can only be mined with the axes provided for this purpose. With all other tools, you can destroy the block, but not harvest anything. When the block is dismantled, you get it back and have to reposition it to harvest. This is so that you can't harvest endlessly with one mouse button held down. The speed of the axes is increased and XP is greatly reduced. Installation copy the folder in to your Mods-folder (local or server-side) - restart - ready Modders Of course, you can still change some of the mod, such as adding more resources and even more axes. Download https://github.com/OmitLeChuck/ressource_block Screens
  11. Hi @doughphunghus, I find the idea with the display of the names (Hide HP Bar But Show Name) really great. I downloaded it right away and tried it once. The display works, but I found the alignment of the text (left) not so nice and then tested a little how I can make it nicer. Here is my result (only windows.xml): <remove xpath="/windows/window[@name='windowTargetBar']"/> <append xpath="/windows"> <window name="windowTargetBar" controller="TargetBar" visibility="always"> <rect pos="-200,-85" width="400" height="36"> <sprite depth="1" name="border" color="0,0,0,0" type="sliced" width="400" globalopacity="false" /> <filledsprite depth="2" name="BarContent" type="filled" color="0,0,0,0" width="400" fill="{fill}" globalopacity="false" /> <label depth="3" name="TextContent" pos="200,-4" font_size="15" color="255,200,200" justify="center" pivot="center" text="{name}" height="30" /> <label depth="5" name="MinionCount" pos="482,-13" font_size="30" color="0,0,0,0" justify="left" pivot="topleft" text="x{minioncount}" height="30" effect="Outline8" effect_color="0,0,0,255" effect_distance="2,2" /> </rect> </window> </append> It will look like this in the game (sorry i play german ) I have made other adjustments to the UI, but here it is only about the display of the name, and that works. Then one more hint. The xui.xml does not need to be adjusted at all. The windowTargetBar is already included in the compass group. Greetings
  12. As I wrote in the first post, you can really do quite a lot. But I also promised to explain everything once. Let's take a look at the list and check it off: spawn zombies or other entities (also in hordes) βœ”οΈ teleport players βœ”οΈ give items to players apply buffs and also query them show tooltips play sounds send messages to the chat monitor and query the log and also the chat βœ”οΈ determine player positions open up windows execute twitch commands create own events βœ”οΈ show infos in a ticker way with tooltips give quests to the player watch server events βœ”οΈ So there are still a few things to check off about. Give items to players, play sound, show tooltips in a ticker way, ... There is always the need to simply execute commands on the console, and there are the commands that are available in the server managers (such as CPM or server tools) help. Of course, it is helpful to build a function that helps you. Example: function executeConsoleCommand($command) { $command = is_array($command) ? implode(' ', $command) : $command; $url = 'http://<serverip>:<mapport>/api/executeconsolecommand?adminuser=myadmintoken&admintoken=verysecrettoken&raw=true&command=' . urlencode($command); $ch = curl_init(); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => $url]); $return = curl_exec($ch); curl_close($ch); return $return ?? null; } With this, you can do the following nice things with the help of commands that are available in CPM or similar: // give item to players executeConsoleCommand(['cpm-giveplus', $steamid, $itemname, $amount, $quality, $usages]); // play sounds executeConsoleCommand(['playsound', $steamid, $soundname]); // show tooltips to evry online player executeConsoleCommand(['cpm-tooltip', 'all', $nameOfTheToolTipBuff]); But sometimes it is necessary to run some things that do not work on the server, but even here there is a great solution. Namely the execution on the client itself. For this in CPM there is the command 'eoc' (executeonclient) which helps you there. The cool thing you can do is for example open a game window on the client to show it 'static' information there. What does it take? A few things. First, of course, we need a window, we create that in windows.xml: <window name="infoWindow" anchor="CenterCenter" pos="0,0" width="150" height="150"> <rect name="content" pos="0,0"> <label depth="4" name="name" width="50" height="50" color="255,255,255" pivot="center" justify="center" text="THE INFO" font_size="70"/> </rect> </window> and a 'window_group in the 'xui.xml'. <window_group name="INFOGROUP"> <window name="infoWindow"/> </window_group> then of course we need a function that facilitates the execution on the client: function executeOnClient($steamid, $command): void { $command = is_array($command) ? implode(' ', $command) : $command; executeConsoleCommand(['eoc', $steamid, '"' . $command . '"']); } then the rest is not bad at all: // open a window executeOnClient($steamid, ['xui', 'open', 'INFOGROUP', '1', '1']); // close a window executeOnClient($steamid, ['xui', 'close', 'INFOGROUP', '1']); That was it already ... I think I have now written everything once in detail and am very happy about feedback. If someone has still more ideas, what one can make in such a way, I am pleased about it also very much. Best regards from the north of Germany dwarfmaster
  13. Thanks to @pharrisee for the tip with the SSE! That has of course changed some procedure, how to monitor the log or the chat best. Immediately implemented it, of course, which cost me a little time, but it was absolutely worth it. The big advantage of SSE is the low load and the synchronous processing of the inputs or the reception of certain events. This means that inputs in the chat take place without any delay and can be reacted to immediately. The same is true for events like a kill, which is registered immediately without taking a few seconds. The implementation in PHP for this is in principle quite simple, if you have dealt with the topic a little bit. I used an external library for this (again, thanks to @pharrisee for the recommendation) https://github.com/eislambey/php-eventsource After including the library, you have to start a process that does the monitoring. This can look like the following: $es = new EventSource('http://<serverip>:<mapport>/sse/log?adminuser=myadmintoken&admintoken=verysecrettoken'); $es->onMessage(function (Event $event) { new Logdispatch($event->data); }); $es->connect(); Important! For this, of course, the server must already be running, otherwise the connection will not work. So it may only be started when the live map is accessible. Behind the class 'Logdispatch' the actual parsing of the log entries takes place, of which there are quite a lot. I decided to do a pre-sorting first, so that not every message is processed and if then also from the correct endpoint. It then looks like this: class Logdispatch { /** * @throws Exception */ public function __construct($entry) { $entry = json_decode($entry, true); if (isset($entry['type']) && $entry['type'] == 'Log') { if (isChat($entry['msg'])) { new Chat(new ChatEntry($entry)); } else if (isServerEvent($entry['msg'])) { new Serverevents(new ServerEventEntry($entry)); } } } } What happens here is that only entries of the type 'Log' are processed, because only there is the information interesting for us. With 'isChat()' and with 'isServerEvent()' we sort out if the arrived log entry is a chat or a server event. Here is an example: function isChat($message): bool { if (isStartingWith($message, 'Chat') && !isContaining($message, 'non-player')) { $return = true; } return $return ?? false; } This identifies all chat entries and at the same time filters out messages from the server ('non-player'). With this information we can then trigger actions like in my previous POST, but much more synchronously. What we don't get at this point, however, is the problem of having events that are repetitive and precise in time. Like for example every 10 seconds to check if there is a blood moon and possibly send new zombies. For this I have already described that you can create a systemd service, but there are other ways. This one is a little bit like getting a text message directly from hell and actually hurts just looking at it, but it works stable and can be used in the user context: user@ubuntu:~$ crontab -e SDTD="/<path_to_your_script>/7d2d.sh" * * * * * ${SDTD} * * * * * ( sleep 10; ${SDTD}) * * * * * ( sleep 20; ${SDTD}) * * * * * ( sleep 30; ${SDTD}) * * * * * ( sleep 40; ${SDTD}) * * * * * ( sleep 50; ${SDTD}) But also a great solution is the Dispatcher from @pharrisee which he once quickly developed. You can find it at: https://github.com/pharrisee/dispatcher The big advantage here, of course, is that this runs on both Linux and Windows, since it's written in golang.
  14. Monitor and query the log and also the chat Why would I want to do that? Monitoring the log and the chat are central elements to trigger certain events in the game, or to enable players to enter things in the chat and react to them. The events that can be monitored in the log are, for example. login / join death of a player kill (zombie, animal, player) levelup The chat can be read out and reacted to depending on how you want to read out commands. The best way to do this is with a prefix. Most often the '/' is used for this. Example for teleporting to the home base: PLAYERNAME: /home How can I make this happen? Here, too, the API helps us where we can quite easily get a number of log entries specified by us. Example for getting the last 200 entries: curl http://<serverip>:<mapport>/api/getlog?adminuser=myadmintoken&admintoken=verysecrettoken&count=-200 Of course, the response then just needs to be evaluated. This is also supplied with format JSON, which makes it a bit easy. Example: { "firstLine": 10000, "lastLine": 10200, "entries": [ { "date": "2022-05-16", "time": "10:37:56", "uptime": "0", "msg": "Chat (from '-non-player-', entity id '-1', to 'Global'): 'SERVER': Test", "trace": "", "type": "Log" }, {...}, {...}, {...} ] } Simply iterate through the 'entries' array and evaluate the 'msg' accordingly. It contains exactly what we need. You just have to parse such a message and check if there is a message in it or not to trigger a command. Example: $parts = preg_split('/(Chat \(from \'|\', entity id \'|\', to \'Global\'\): \'|\':)/', $entry); To test PHP-RegEx I recommend this page here: https://www.phpliveregex.com/#tab-preg-split This really helped me a lot, because there is a lot to parse. These individual (chat) pieces then provide you with all the information you need to start further actions: $steamid = $parts[1]; $entityid = $parts[2]; $playername = $parts[3]; $message = $parts[4]; if (isStartingWith($message, '/')) { $command = substr($this->message, 1); } With the variable $command you can then trigger a teleport for example. Here is an example for the input '/home' which triggers the command 'cpm-teleportplayerhome': $url = 'http://<serverip>:<mapport>/api/executeconsolecommand?adminuser=myadmintoken&admintoken=verysecrettoken&raw=true&command=' . urlencode('cpm-teleportplayerhome '.$steamid); $ch = curl_init(); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => $url]); $result = curl_exec($ch); curl_close($ch); 'cpm-teleportplayerhome' teleports the player to his active bedroll or bed. That's all you need to monitor the chat input. For monitoring server events, a little more is needed, because there are a few more of them. Here are a few examples of what the messages in the logs can look like and how best to parse them. // JOIN // Message = Player connected with ID 'Steam_12345678912345678' 'EOS_00055455dg45h45hhdd54n5dh45dh412' and IP '192.168.178.123' named 'dwarfmaster' $parts = preg_split('/(ID \'|\' \'|\')/', $message); $steamid = trim($parts[1]); $playername = trim($parts[6]); $eosid = trim($parts[2]); $ip = trim($parts[4]); // KILL // Message = entityKilled: dwarfmaster (Steam_12345678912345678) killed zombie zombieFatCopRadiated with dwarfmaster-Gun $parts = preg_split('/(.*entityKilled: |\) killed |\(| with )/', $message); $typeParts = explode(' ', $parts[3]); $animal = (trim($typeParts[0]) == 'animal'); // checks if entity is an animal > true/false $entity = trim($typeParts[1]); $with = trim($parts[4]); $playername = trim($parts[1]); $steamid = trim($parts[2]); // DEATH // Message = playerDied: dwarfmaster (Steam_12345678912345678) died @ 250 50 519 $parts = preg_split('/(playerDied: | \(|\) died @ )/', $message); $deathLocationParts = explode(' ', $parts[3]); $playername = trim($parts[1]); $steamid = trim($parts[2]); $deathLocation = ['x' => intval($deathLocationParts[0]), 'y' => intval($deathLocationParts[1]), 'z' => intval($deathLocationParts[2])]; // LEVELUP // Message = playerLeveled: dwarfmaster (Steam_12345678912345678) made level 545 (was 544) $parts = preg_split('/(playerLeveled: |\)| made level |\(|was )/', $this->entry['msg']); $playername = trim($parts[1]); $steamid = trim($parts[2]); $newlevel = intval($parts[4]); $oldlevel = intval($parts[6]); // LEFT // Message = Player disconnected: EntityID=616, PltfmId='Steam_12345678912345678', CrossId='EOS_00055455dg45h45hhdd54n5dh45dh412', OwnerID='Steam_12345678912345678', PlayerName='dwarfmaster' $parts = preg_split('/(\')/', $message); $steamid = trim($parts[1]); $playername = trim($parts[7]); With all this information, of course, you can do a lot. Whether that's saving for stats, or showing players in chat who just came onto the server, or even which player just died or killed which zombie. Done. Now we have monitoring of the chat and server events.
  15. How to create an event like the Horde Night? to create an event you need something that takes the component time from you. So a process that makes sure that in certain intervals is queried how the state of the game is and executes commands based on this information. Since my example is in the area of Linux, 'systemd' is a good choice. A construct, which makes it possible to start certain commands exactly to the second. Such a service is divided into two parts. Once the start component (the service) and once the time component. Here is link to a good description for systemd (german): https://wiki.archlinux.de/title/Systemd/Timers But I am sure that there are also good tutorials in English. Just google a little bit. Here is an example of both components: SERVICE [Unit] Description=start event check [Service] ExecStart=/<path_to_your_script>/7d2d.sh events TIMER [Unit] Description=7d2d event check every 10 seconds [Timer] OnBootSec=10 OnUnitActiveSec=10 AccuracySec=1 [Install] WantedBy=timers.target What does this do? If activated, this service starts the bash file 7d2d.sh with the parameter events. This happens every 10 seconds. Of course, you can make this period shorter, but for an event this is not necessary. In this '.sh' file I can of course do everything that a bash can do. Among other things of course also PHP start. Example: #!/bin/bash php /<path_to_php_script>/startup.php $@ This PHP script can query or trigger anything that the API can do and of course execute commands that get you the necessary information, and also start actions. Here is an example of how a horde night can look like: public function event() { if (EVENT_BLOODMOON) { initEvent(get_class($this)); $locations = getPlayersLocation(); $maxZombies = ((BLOOD_MOON_ENEMY_COUNT * ePLAYERS) > MAX_SPAWNED_ZOMBIES) ? MAX_SPAWNED_ZOMBIES : BLOOD_MOON_ENEMY_COUNT * ePLAYERS; $maxZombiesForPlayer = intval($maxZombies / ePLAYERS); $allZombies = getEntities(); $zombiesInRadius = []; if (count($allZombies) < MAX_SPAWNED_ZOMBIES) { foreach ($locations as $player) { $zombiesInPlayerRadius = getCustomEntities($player['position'], 'Zombie', LAND_CLAIM_SIZE * 3); $playerAtPlayer = count(getCustomEntities($player['position'], 'Player', LAND_CLAIM_SIZE * 3)); $zombiesInRadius += $zombiesInPlayerRadius; $zombiesAtPlayer = ($playerAtPlayer > 1) ? intval(count($zombiesInPlayerRadius) / $playerAtPlayer) : count($zombiesInPlayerRadius); if (($maxZombiesForPlayer - $zombiesAtPlayer) > 0) { targetedHorde($player[STEAM_ID], ($maxZombiesForPlayer - $zombiesAtPlayer)); } } } cleanupEntities($allZombies, $zombiesInRadius); } else { endEvent(get_class($this)); } } Explanation lines by lines of what is happening there. EVENT_BLOODMOON => true/false Here, simply the time on the server is queried and checked whether it corresponds to the time in which the event should run. The time query is very simple via the API: curl http://<serverip>:<mapport>/api/getstats The result is a JSON which can be queried in PHP without any problems: { gametime: { days: 517, hours: 23, minutes: 3 }, players: 2, hostiles: 10, animals: 5 } So in this case, you only need to determine if it is the 7/8 day and the time is between 10pm and 4am. initEvent Here, simply a BUFF is set, which indicates that the event is started. Setting a buff is quite simple. I used the command: buffplayer Steam_12321313212131 eventBuffName getPlayerLocations() Very important to determine what is happening around the player's position during the event. This query also returns a JSON which can be saved for later use: curl http://<serverip>:<mapport>/api/getplayerslocation JSON: [ { steamid: "Steam_76561198075097605", name: "dwarfmaster", online: true, position: { x: 3073, y: 37, z: 818 } } ] The variable $locations now contains all positions of the players. maxZombies This is just simple math to calculate how many zombies should be spawned. You just have to play around a bit getEntities() This is a little more complex, because here the goal is to determine everything that is already spawned and what state it is in (dead/alive). For this I use the command: 'le' which returns a result that looks something like this: 1. id=415881, [type=EntityZombie, name=zombieSoldierFeral, id=415881], pos=(3063.3, 37.6, 819.7), rot=(0.0, 21.8, 0.0), lifetime=float.Max, remote=False, dead=False, health=232 2. id=415880, [type=EntityZombie, name=zombieSkateboarder, id=415880], pos=(3054.8, 37.0, 817.5), rot=(0.0, 270.0, 0.0), lifetime=float.Max, remote=False, dead=False, health=221 3. id=415879, [type=EntityZombie, name=zombieSteve, id=415879], pos=(3068.9, 37.1, 815.6), rot=(0.0, 113.1, 0.0), lifetime=float.Max, remote=False, dead=False, health=100 4. id=415878, [type=EntityZombie, name=zombieSkateboarderRadiated, id=415878], pos=(3063.9, 37.1, 817.1), rot=(0.0, 117.8, 0.0), lifetime=float.Max, remote=False, dead=False, health=785 5. id=415877, [type=EntityZombie, name=zombieTomClark, id=415877], pos=(3070.2, 37.1, 816.5), rot=(0.0, 98.6, 0.0), lifetime=float.Max, remote=False, dead=False, health=141 6. id=415876, [type=EntityZombie, name=zombieSteveCrawlerFeral, id=415876], pos=(3062.9, 37.0, 817.2), rot=(0.0, 266.0, 0.0), lifetime=float.Max, remote=False, dead=False, health=144 7. id=415875, [type=EntityZombie, name=zombieSteveRadiated, id=415875], pos=(3062.8, 37.1, 821.6), rot=(0.0, 27.0, 0.0), lifetime=float.Max, remote=False, dead=False, health=505 8. id=415874, [type=EntityZombie, name=zombieSteveCrawler, id=415874], pos=(3063.6, 37.0, 819.6), rot=(0.0, 93.1, 0.0), lifetime=float.Max, remote=False, dead=False, health=74 9. id=616, [type=EntityPlayer, name=dwarfmaster, id=616], pos=(3073.3, 37.2, 818.0), rot=(5.6, 289.7, 0.0), lifetime=float.Max, remote=True, dead=False, health=200 Total of 9 in the game Of course, this has to be parsed first, so that you can use it well in PHP. This can be done well with RegEx. Example: $parts = preg_split('/(.*\. id=|, \[type=|, name=|, id=.*pos=\(|\).*dead=|, health=|, )/', $entityline); The single parts can be put into an object or into an array. How you like it. I think the next lines are almost self-explanatory, and it gets exciting again with the following command: getCustomEntities What happens there in the background is that it determines what entities are in a radius around the player. This happens with the command: 'listcustomentity'. Example: listcustomentity x z radius type x, z stand for the position of the player and radius for the radius in which the player should look. The parsing is almost the same as the 'le' command. With this information, we can now determine exactly how many new zombies to give the player. We pass this to the command: 'cpm-targetedhorde'. Example: cpm-targetedhorde Steam_31213132131 15 This command from the mod CPM spawns the zombies, and these are then also set directly on the player and want to eat him. Just as it should be. πŸ˜‡ We're pretty much done, just one more thing, and we'll have it. cleanupEntities This is really important, because every dead zombie that is lying around somewhere costs performance, and it quickly starts to lag if you don't remove these corpses. So this command looks how many zombies have the status dead and then removes them. This then with the command: cpm-entityremove 123 Done. Now we have our own hordes night. For questions, please always ask
  16. Hi Survivors, First, I would like to say that I am neither a developer in the true sense of the word, nor a fully trained administrator or anything like that. Everything in the following I have taught myself, and that only for the reason that it is fun for me. So if you discover technical gaps or find out that things are done differently nowadays, feel free to contact me, because I like to take advice that helps me to have even more fun and joy with this project. But now back to the topic. My plan is, that I show you ( because I enjoy it ) in this post regularly some nice things, and how I implemented them with PHP, bash, XML, ... this post should be the introduction. If you have any questions, of course feel free to ask, that's why we are here. πŸ˜‡ What is it actually about? Nowadays, running a server is basically very simple. Download, adjust the configuration and maybe a few mods for optics and special items purely, start and ready. But it can be so much better and with so much more functionality, because 7D2D can do great things with a few small tools and the API. What can a server look like? Operating system: Linux ( I prefer Ubuntu ). This includes then for the operation in the operating system installed PHP (best in a 7 version) in the client version (PHP-CLI) xmlstarlet (to read or edit XML files in bash) LinuxGSM ( https://linuxgsm.com/servers/sdtdserver/ ) great tool to install, update, run the server Kernel-Mods Besides all the mods that make the game itself prettier, there are mods that drastically expand the range of functions and should therefore be mandatory. Allocs Server-Fixes and Live-Map ( https://7dtd.illy.bz/wiki/Server fixes#Download ) Without this mod(s) basically nothing would work, because without the API all efforts with PHP or bash would be waste. So the API is the core for everything else. CPM - CSMM Patron's Mod ( https://docs.csmm.app/en/CPM/ ) This mod provides a number of useful functions that can be used in the console. Among other things, teleports, spawning of hordes or functions that allow the player to pack items in the backpack and much more. 7dtd-ServerTools ( https://github.com/dmustanger/7dtd-ServerTools ) Similar to CPM, the server tools provide a lot of functionality to help you run the server and make it even cooler. From my point of view, the biggest strength of the server tools is the management of the zones via live XMLs. Moreover, it is OpenSource. There are certainly a few more mods in this direction, but with these three I have had the best experience so far. All beginnings are difficult 😒 To run the first command with PHP or bash it is necessary to set one important thing. Namely, the API token. This must be done in the webpermissions.xml which is usually located in the main directory of the saves. Here is an example: <?xml version="1.0" encoding="UTF-8"?> <webpermissions> <admintokens> <token name="myadmintoken" token="verysecrettoken" permission_level="0"/> </admintokens> <permissions> <!-- permissions for the map --> </permissions> </webpermissions> This token opens up endless possibilities with the help of the API. At this point, it is important to choose the right 'permission_level', because some things only work correctly with level = 0 (which is the admin level). Once that is set, you immediately have the ability to send commands through the API using Curl, a browser, or even Postman. Example in bash for displaying the help: curl http://<serverip>:<mapport>/api/executeconsolecommand?adminuser=myadmintoken&admintoken=verysecrettoken&raw=true&command=help Once that is done, and it works, the rest is pretty easy to implement in vanilla PHP. Simple example in PHP: $url = 'http://<serverip>:<mapport>/api/executeconsolecommand?adminuser=myadmintoken&admintoken=verysecrettoken&raw=true&command=' . urlencode('help'); $ch = curl_init(); curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER => true, CURLOPT_URL => $url]); $result = curl_exec($ch); curl_close($ch); Important at this point is to make a 'urlencode' for the actual command, because many commands have additional parameters and already a space can become a problem. Now you can do almost everything you want or what is possible with console commands. This includes, for example (I will describe all of them little by little in following posts): spawn zombies or other entities (also in hordes) teleport players give items to players apply buffs and also query them show tooltips play sounds send messages to the chat monitor and query the log and also the chat determine player positions open up windows execute twitch commands create own events show infos in a ticker way with tooltips give quests to the player watch server events like: join/left die kill levelup but in addition you can do other great things with PHP like creating XML files that are otherwise very complex. Like for example entitygroups or tooltips. This should be enough to get you started. As the next post, I will try to explain how to make an own event, similar to the Horde Night. CU and gladly asks questions. You are welcome ...
  17. Hello all, this is now my 2nd mod, which I am happy to share with you. This mod doesn't actually do that much, and has just little effects on the game itself. It only shows a current rank in the list of buffs. This rank can be reached by reaching a certain player level. This must/can be configured in the buffs.xml. Download the mod here: >>> github.com -> dwarfmaster_ranks Also, have a look at the README.md for instructions and help . Works both locally and server-side. For questions, requests comments and the like, just text meπŸ˜‡
  18. Hi @ktrain, the download represent a basic config. So every value is set to default. Even the logo and the links. You can manipulate the config.json to your needs My Demo additionally just contents the statistics and some contents in the information area and of course live playing data like my server-map and zones How to set up is described in the readme.md on github. Greetings
  19. Hello all, I have tried a little, because I find it exciting to see what is happening on the server. I mean, who has killed which zombies or animals and with what. So the idea was to show this also on the live map. The result is another JSON file that can be filled to display this data. (stats.json) But I'm not sure if this could be interesting for you, because the filling and gathering of the data is of course not that easy, and you need a little technical experience. Therefore, the question here, whether I should include this in the current module and if so how, because by default there is no data. So you see what I mean, you can look at the live map of my server, where I test from time to time. http://der-heimat-hafen.de Just click on 'Statistik' in the left menu to get an impression of what I'm talking about. (mostly german, sorry) .... and of course it is a draft version πŸ˜‡ I would be happy about your feedback, but of course I also take your questions. Greetings
  20. @Telric you saved my day 🀩 Thx's a lot ... this is now working very fine and the users are loving it 😁
  21. Hi all, I created a tiny XML - Mod to enable a ranking with names (Captain, Sergeant, ...) and wanted to add some abilities to these rank like unlocking recipes. So I build a buffs like this: <buff name="buffLevel04" name_key="buffLevel04Name" remove_on_death="false" icon="server_favorite" icon_color="255,170,69"> <display_value_key value="Unteroffizier"/> <display_value value="Unteroffizier"/> <effect_group> <passive_effect name="RecipeTagUnlocked" tags="modAugerSilencer,cowHelmet"/> </effect_group> </buff> and one of the regarding recipe looks like that: <recipe name="cowHelmet" count="1" craft_time="120" craft_area="homeHarbourMachine" tags="learnable"> <ingredient name="resourceRawDiamond" count="1"/> <ingredient name="resourceLeather" count="500"/> </recipe> The Item(Modifier) looks like this: <item_modifier name="cowHelmet" installable_tags="head" modifier_tags="dye" blocked_tags="noMods,clothing" type="attachment"> <property name="CustomIcon" value="decoCowSkull"/> <property name="Stacknumber" value="1"/> <property name="DescriptionKey" value="cowHelmetDesc"/> <property name="Group" value="Mods"/> <property name="DropMeshfile" value="#Other/Items?Misc/sack_droppedPrefab.prefab"/> <property name="EconomicValue" value="440"/> <property name="UnlockedBy" value="buffLevel04,buffLevel05,buffLevel06,buffLevel07,buffLevel08,buffLevel09,buffLevel10"/> <effect_group tiered="false"> <triggered_effect trigger="onSelfEquipStart" action="AttachPrefabToEntity" prefab="Entities/OutdoorDecor/cowSkullPrefab" parent_transform="Head" local_offset="-0.44,0,0.04" local_rotation="0,0,90"> <requirement name="!IsFPV"/> </triggered_effect> <triggered_effect trigger="onSelfEquipStart" action="RemovePrefabFromEntity" prefab="Entities/OutdoorDecor/cowSkullPrefab"> <requirement name="IsFPV"/> </triggered_effect> <triggered_effect trigger="onSelfEquipStop" action="RemovePrefabFromEntity" prefab="Entities/OutdoorDecor/cowSkullPrefab"/> </effect_group> <effect_group tiered="false"> <passive_effect name="AttributeLevel" tags="attStrength" operation="base_add" value="1"/> <passive_effect name="PhysicalDamageResist" operation="base_add" value="1"/> <passive_effect name="HypothermalResist" operation="base_add" value="10.5,13.2"/> <passive_effect name="HyperthermalResist" operation="base_add" value="1.5,2.5"/> <passive_effect name="ElementalDamageResist" operation="base_add" value="1" tags="heat,electrical"/> <passive_effect name="AttributeLevel" tags="attFortitude" operation="base_add" value="1"/> <passive_effect name="AttributeLevel" tags="attAgility" operation="base_add" value="1"/> </effect_group> </item_modifier> But when I execute, i.e. 'buff buffLevel04' the recipes are still locked 😒 What is missing? Any Ideas? PS: The item recipes should be unlocked even in higher levels/ranks, so that's why the UnlockedBy attribute is so long πŸ˜‰
  22. Hi @Shebuk, no problem. I think we can find the issue you are facing. Some questions to investigate: * Do you have any additional JavaScript added to your map? * which browser and version are you using? * could you send me a direct message with your config.json file? So that i can reproduce in my dev environment? * are there any error messages when you open the dev console? (in Chrome 'F12' and tab 'console')? We are around the world of JavaScript and that is sometimes a tiny pain in the ... πŸ˜‡
  23. Hi @Shebuk, I guess that it could depend on the configured rights you have. There are two rights to set up in the webpermissions.xml for that: <permission module="webapi.viewallclaims" permission_level="2000"/> <permission module="webapi.getlandclaims" permission_level="2000"/> You can check the correct permission if you just call the api like this: http://[IP-ADRESS:PORT]/api/getlandclaims. This should normally output something like that in your browser: { claimsize: 50, claimowners: [{ steamid: "EOS_0056df54654kjdhgkjdfhgk5465dsdg2", claimactive: true, playername: null, claims: [{ x: 1747, y: 28, z: 1698 }, { x: 1747, y: 13, z: 1342 } ] } ] } Hopefully that helps πŸ˜‡
  24. Hi @Kazina, Reset-Zones are normally only then present if you are using any kind of Server-Manager like CSMM/CPM or Server-Tools etc. The logic behind that is just to delete the Region-Files where all the SaveGameData for the environment is saved. These files are located in your SaveGameFolder/MapName/GameName/Region and the format is i.e. r.0.-1.7rg. If you don't use a Server-Manager or something else, you do not need to configure that part, and you can leave the zones file empty. Concering the traders, you could find the positions of the traders in the prefab.xml of your used map in your World-Directory. Just open that file with notepad or similiar > search for trader, and you will find lines like: <decoration type="model" name="trader_rekt" position="1420,38,3269" rotation="2" /> so you could add this information to your taders.json like this: { "name": "Rekt", "x": "1420", "z": "3269" } Hopefully that helps
Γ—
Γ—
  • Create New...