-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from jonathan-robertson/dev
Initial Pre-Release
- Loading branch information
Showing
13 changed files
with
366 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
Key,File,Type,UsedInMainMenu,NoTranslate,english,Context / Alternate Text,german,latam,french,italian,japanese,koreana,polish,brazilian,russian,turkish,schinese,tchinese,spanish | ||
buffDaysRemainingVendingExpirationFormat,UI,XUI,,?,{0:0} Days,,{0:0} Tage,{0:0} Días,{0:0} Jours,{0:0} Giorni,{0:0} 日,{0:0} 일,{0:0} Dni,{0:0} Dias,{0:0} Дней,{0:0} Gün,{0:0} 天数,{0:0} 天,{0:0} Días | ||
buffDaysRemainingVendingExpirationName,buffs,Buff,,x,Vending Machine,,Automat,Máquina expendedora,Distributeur automatique,Distributore automatico,自動販売機,자판기,Automat sprzedający,Máquina de Vendas,Торговый автомат,Otomat,自动贩卖机,自動販賣機,Máquina expendedora | ||
buffDaysRemainingVendingExpirationDesc,buffs,Buff,,x,Your vending machine rental will expire in [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] days.,,Ihre Automatenmiete läuft in [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] Tagen ab.,El alquiler de su máquina expendedora caducará en [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] días.,Votre location de distributeur expirera dans [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] jours.,Il noleggio del tuo distributore automatico scadrà tra [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] giorni.,自動販売機のレンタルは [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] 日後に期限切れになります.,자판기 대여가 [007fff]{cvar(daysRemainingVendingExpiration:0)}일 후에 만료됩니다.,Wypożyczenie automatu wygaśnie za [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] dni.,O aluguel da máquina de venda automática expira em [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] dias.,Срок аренды вашего торгового автомата истекает через [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] дней.,Otomat kiralama süreniz [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] gün içinde sona erecek.,您的自动售货机租赁将在 [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] 天后到期.,您的自動售貨機租賃將在 [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] 天后到期.,El alquiler de su máquina expendedora caducará en [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] días. | ||
buffDaysRemainingVendingExpirationTooltip,buffs,Buff,,x,Your vending machine rental will expire in [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] days.,,Ihre Automatenmiete läuft in [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] Tagen ab.,El alquiler de su máquina expendedora caducará en [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] días.,Votre location de distributeur expirera dans [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] jours.,Il noleggio del tuo distributore automatico scadrà tra [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] giorni.,自動販売機のレンタルは [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] 日後に期限切れになります.,자판기 대여가 [007fff]{cvar(daysRemainingVendingExpiration:0)}일 후에 만료됩니다.,Wypożyczenie automatu wygaśnie za [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] dni.,O aluguel da máquina de venda automática expira em [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] dias.,Срок аренды вашего торгового автомата истекает через [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] дней.,Otomat kiralama süreniz [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] gün içinde sona erecek.,您的自动售货机租赁将在 [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] 天后到期.,您的自動售貨機租賃將在 [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] 天后到期.,El alquiler de su máquina expendedora caducará en [007fff]{cvar(daysRemainingVendingExpiration:0)}[-] días. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<config> | ||
<set xpath="/windows/window[@name='windowTrader']/panel[@name='content']/rect[@name='searchControls']/label[@text='{renttimeleft}']/@text">{# localization('xuiExpires')}: {cvar(daysRemainingVendingExpiration:0)} {# localization('xuiBuffStatDays')}</set> | ||
</config> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
<config> | ||
<append xpath="/buffs"> | ||
<buff name="buffDaysRemainingVendingExpiration" name_key="buffDaysRemainingVendingExpirationName" description_key="buffDaysRemainingVendingExpirationDesc" tooltip_key="buffDaysRemainingVendingExpirationTooltip" icon="ui_game_symbol_vending" icon_color="0,127,255"> | ||
<duration value="30" /> | ||
<stack_type value="duration" /> | ||
<display_value_key value="buffDaysRemainingVendingExpirationFormat" /> | ||
<display_value value="daysRemainingVendingExpiration" /> | ||
</buff> | ||
</append> | ||
</config> |
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<xml> | ||
<ModInfo> | ||
<Name value="Days Remaining" /> | ||
<Description value="Update trader restock date and vending expiration date to show days until vs date of." /> | ||
<Author value="Jonathan Robertson (Kanaverum)" /> | ||
<Version value="0.1.0" /> | ||
<Website value="https://github.com/jonathan-robertson/days-remaining" /> | ||
</ModInfo> | ||
</xml> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Days Remaining | ||
|
||
[![🧪 Tested On](https://img.shields.io/badge/🧪%20Tested%20On-A20.6%20b9-blue.svg)](https://7daystodie.com/) [![📦 Automated Release](https://github.com/jonathan-robertson/days-remaining/actions/workflows/release.yml/badge.svg)](https://github.com/jonathan-robertson/days-remaining/actions/workflows/release.yml) | ||
|
||
- [Days Remaining](#days-remaining) | ||
- [Summary](#summary) | ||
- [Sister Project](#sister-project) | ||
- [Compatibility](#compatibility) | ||
|
||
## Summary | ||
|
||
7 Days to Die mod: update trader restock date and vending expiration date to show days until vs date of. | ||
|
||
This mod does not alter the actual days within a server (many components in the game rely on server/world time increasing); it simply updates how the days are reported for Trader Restock and the Rentable Vending Machine Expiration Date. | ||
|
||
## Sister Project | ||
|
||
This mod is designed to be used with another to complete your experience: | ||
|
||
- [Days of the Week](https://github.com/jonathan-robertson/days-of-the-week) | ||
- Replace days count in UI with a day of the week | ||
- *be sure to use the `windows-days-remaining.xml` option in this mod to get the best experience* | ||
|
||
## Compatibility | ||
|
||
Environment | Compatible | Does EAC Need to be Disabled? | Who needs to install? | ||
--- | --- | --- | --- | ||
Dedicated Server | Yes | no | only server | ||
Peer-to-Peer Hosting | Yes | only on the host | only the host | ||
Single Player Game | Yes | Yes | self (of course) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
using System; | ||
|
||
namespace DaysRemaining | ||
{ | ||
internal class Helpers | ||
{ | ||
private static readonly ModLog<Helpers> _log = new ModLog<Helpers>(); | ||
private static readonly string CVAR_VENDING_EXPIRATION = "daysRemainingVendingExpiration"; | ||
private static readonly string BUFF_VENDING_EXPIRATION = "buffDaysRemainingVendingExpiration"; | ||
|
||
public static bool TryGetTileEntityVendingMachine(Vector3i blockPos, out TileEntityVendingMachine tileEntityVendingMachine) | ||
{ | ||
var world = GameManager.Instance.World; | ||
var tileEntity = world.GetTileEntity(world.ChunkCache.ClusterIdx, blockPos); | ||
if (tileEntity == null || !(tileEntity is TileEntityVendingMachine te)) | ||
{ | ||
tileEntityVendingMachine = null; | ||
return false; | ||
} | ||
tileEntityVendingMachine = te; | ||
return true; | ||
} | ||
|
||
public static bool TryGetTileEntityVendingMachine(TileEntity tileEntity, out TileEntityVendingMachine tileEntityVendingMachine) | ||
{ | ||
if (tileEntity is TileEntityVendingMachine te) | ||
{ | ||
tileEntityVendingMachine = te; | ||
return true; | ||
} | ||
tileEntityVendingMachine = null; | ||
return false; | ||
} | ||
|
||
public static bool TryGetOwner(ILockable lockable, out PlatformUserIdentifierAbs owner) | ||
{ | ||
owner = lockable.GetOwner(); | ||
return owner != null; | ||
} | ||
|
||
public static bool TryGetClientInfo(PlatformUserIdentifierAbs id, out ClientInfo clientInfo) | ||
{ | ||
clientInfo = ConnectionManager.Instance.Clients.ForUserId(id); | ||
return clientInfo != null; | ||
} | ||
|
||
public static bool TryGetClientInfo(int entityId, out ClientInfo clientInfo) | ||
{ | ||
clientInfo = ConnectionManager.Instance.Clients.ForEntityId(entityId); | ||
return clientInfo != null; | ||
} | ||
|
||
public static bool TryGetVendingMachineRentalData(Vector3i blockPos, out PlatformUserIdentifierAbs owner, out int rentalEndDay) | ||
{ | ||
if (!TryGetTileEntityVendingMachine(blockPos, out var tileEntityVendingMachine)) | ||
{ | ||
_log.Warn($"could not find vending machine tile entity at {blockPos}"); | ||
owner = null; | ||
rentalEndDay = 0; | ||
return false; | ||
} | ||
owner = tileEntityVendingMachine.GetOwner(); | ||
rentalEndDay = tileEntityVendingMachine.RentalEndDay; | ||
return true; | ||
} | ||
|
||
/// <summary> | ||
/// Call this to update the player's client-side data related to vending expiration date. | ||
/// </summary> | ||
/// <param name="clientInfo">ClientInfo containing the current rental information.</param> | ||
/// <param name="player">EntityPlayer to update.</param> | ||
public static void SetExpirationDaysRemaining(ClientInfo clientInfo, EntityPlayer player) | ||
{ | ||
if (clientInfo == null || player == null) | ||
{ | ||
_log.Warn($"ClientInfo and EntityPlayer params must not be null; ClientInfo {(clientInfo != null ? "exists" : "does not exist")}, EntityPlayer {(player != null ? "exists" : "does not exist")}."); | ||
return; | ||
} | ||
if (clientInfo.latestPlayerData.rentalEndDay == 0) | ||
{ | ||
return; | ||
} | ||
var daysRemaining = Math.Max(clientInfo.latestPlayerData.rentalEndDay - GameUtils.WorldTimeToDays(GameManager.Instance.World.worldTime), 0); | ||
if (daysRemaining != player.GetCVar(CVAR_VENDING_EXPIRATION)) | ||
{ | ||
player.SetCVar(CVAR_VENDING_EXPIRATION, daysRemaining); | ||
_ = player.Buffs.AddBuff(BUFF_VENDING_EXPIRATION); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
using HarmonyLib; | ||
using System; | ||
using System.Reflection; | ||
|
||
namespace DaysRemaining | ||
{ | ||
internal class ModApi : IModApi | ||
{ | ||
private static readonly ModLog<ModApi> _log = new ModLog<ModApi>(); | ||
|
||
public static bool DebugMode { get; set; } = true; // TODO: disable before release | ||
|
||
public void InitMod(Mod _modInstance) | ||
{ | ||
var harmony = new Harmony(GetType().ToString()); | ||
harmony.PatchAll(Assembly.GetExecutingAssembly()); | ||
|
||
// TODO: confirm if rental state only updates when vend is closed | ||
// TODO: on rental agreement changed, calculate and send cvar | ||
|
||
ModEvents.PlayerSpawnedInWorld.RegisterHandler(OnPlayerSpawnedInWorld); | ||
} | ||
|
||
private void OnPlayerSpawnedInWorld(ClientInfo _cInfo, RespawnType _respawnReason, Vector3i _pos) | ||
{ | ||
try | ||
{ | ||
if (_cInfo == null) // is client local? | ||
{ | ||
// TODO: var ppId = ((_cInfo != null) ? _cInfo.InternalId : null) ?? PlatformManager.InternalLocalUserIdentifier; | ||
return; | ||
} | ||
|
||
switch (_respawnReason) | ||
{ | ||
case RespawnType.JoinMultiplayer: | ||
if (GameManager.Instance.World.Players.dict.TryGetValue(_cInfo.entityId, out var player)) | ||
{ | ||
Helpers.SetExpirationDaysRemaining(_cInfo, player); | ||
} | ||
return; | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
_log.Error("OnPlayerSpawnedInWorld", e); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
using System; | ||
|
||
namespace DaysRemaining | ||
{ | ||
internal class ModLog<T> | ||
{ | ||
private readonly string _className; | ||
|
||
public ModLog() | ||
{ | ||
_className = typeof(T).FullName; | ||
} | ||
|
||
public void Trace(string message) | ||
{ | ||
if (ModApi.DebugMode) | ||
{ | ||
Log.Out($"[{_className}] TRACE: {message}"); | ||
} | ||
} | ||
|
||
public void Debug(string message) | ||
{ | ||
if (ModApi.DebugMode) | ||
{ | ||
Log.Out($"[{_className}] DEBUG: {message}"); | ||
} | ||
} | ||
|
||
public void Info(string message) | ||
{ | ||
Log.Out($"[{_className}] {message}"); | ||
} | ||
|
||
public void Warn(string message, Exception e = null) | ||
{ | ||
Log.Warning($"[{_className}] {message}"); | ||
if (e != null) | ||
{ | ||
Log.Warning($"[{_className}] {message}\n{e.Message}\n{e.StackTrace}"); | ||
Log.Exception(e); | ||
} | ||
} | ||
|
||
public void Error(string message, Exception e = null) | ||
{ | ||
if (e == null) | ||
{ | ||
Log.Error($"[{_className}] {message}"); | ||
} | ||
else | ||
{ | ||
Log.Error($"[{_className}] {message}\n{e.Message}\n{e.StackTrace}"); | ||
Log.Exception(e); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
using HarmonyLib; | ||
using System; | ||
|
||
namespace DaysRemaining | ||
{ | ||
[HarmonyPatch(typeof(NetPackageTileEntity), "Setup", typeof(TileEntity), typeof(TileEntity.StreamModeWrite), typeof(byte))] | ||
internal class NetPackageTileEntity_Setup_Patches | ||
{ | ||
private static readonly ModLog<NetPackageTileEntity_Setup_Patches> _log = new ModLog<NetPackageTileEntity_Setup_Patches>(); | ||
|
||
/// <summary> | ||
/// Called from server-side NetPackageTileEntity.ProcessPackage after ingesting data from client. | ||
/// Also called from client to update server. | ||
/// </summary> | ||
/// <param name="_te">TileEntity to be inspected if also a TileEntityVendingMachine.</param> | ||
/// <param name="___teWorldPos">Vector3i calculated world position of this tile.</param> | ||
public static void Postfix(TileEntity _te, Vector3i ___teWorldPos) | ||
{ | ||
try | ||
{ | ||
if (Helpers.TryGetTileEntityVendingMachine(_te, out var tileEntityVendingMachine)) | ||
{ | ||
if (Helpers.TryGetOwner(tileEntityVendingMachine, out var owner)) | ||
{ | ||
if (Helpers.TryGetClientInfo(owner, out var clientInfo)) | ||
{ | ||
if (GameManager.Instance.World.Players.dict.TryGetValue(clientInfo.entityId, out var player)) | ||
{ | ||
// update this data on server's end now since we know it'll be on the way next time a player save packet is sent from client. | ||
clientInfo.latestPlayerData.rentedVMPosition = ___teWorldPos; | ||
clientInfo.latestPlayerData.rentalEndDay = tileEntityVendingMachine.RentalEndDay; | ||
// close the open trader (vending machine) window because the cvar cannot auto-refresh its ui value on its own | ||
clientInfo.SendPackage(NetPackageManager.GetPackage<NetPackageConsoleCmdClient>().Setup("xui close trader", true)); | ||
Helpers.SetExpirationDaysRemaining(clientInfo, player); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
_log.Error("Postfix", e); | ||
} | ||
} | ||
} | ||
|
||
[HarmonyPatch(typeof(GameManager), "SetWorldTime")] | ||
internal class GameManager_SetWorldTime_Patches | ||
{ | ||
private static readonly ModLog<GameManager_SetWorldTime_Patches> _log = new ModLog<GameManager_SetWorldTime_Patches>(); | ||
|
||
public static void Postfix() | ||
{ | ||
try | ||
{ | ||
var players = GameManager.Instance.World.Players.list; | ||
for (var i = 0; i < players.Count; i++) | ||
{ | ||
if (Helpers.TryGetClientInfo(players[i].entityId, out var clientInfo)) | ||
{ | ||
Helpers.SetExpirationDaysRemaining(clientInfo, players[i]); | ||
} | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
_log.Error("Postfix", e); | ||
} | ||
} | ||
} | ||
|
||
[HarmonyPatch(typeof(GameManager), "updateTimeOfDay")] | ||
internal class GameManager_updateTimeOfDay_Patches | ||
{ | ||
private static readonly ModLog<GameManager_updateTimeOfDay_Patches> _log = new ModLog<GameManager_updateTimeOfDay_Patches>(); | ||
|
||
public static void Postfix() | ||
{ | ||
try | ||
{ | ||
var players = GameManager.Instance.World.Players.list; | ||
for (var i = 0; i < players.Count; i++) | ||
{ | ||
if (Helpers.TryGetClientInfo(players[i].entityId, out var clientInfo)) | ||
{ | ||
Helpers.SetExpirationDaysRemaining(clientInfo, players[i]); | ||
} | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
_log.Error("Postfix", e); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters