Skip to content

Commit

Permalink
add "refund"
Browse files Browse the repository at this point in the history
deprecate some redeems
add refund cases where it makes sense
  • Loading branch information
Govorunb committed Jul 11, 2024
1 parent f3f1304 commit 553f105
Show file tree
Hide file tree
Showing 21 changed files with 117 additions and 47 deletions.
46 changes: 43 additions & 3 deletions SCHIZO/Commands/Output/CommonResults.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,55 @@ namespace SCHIZO.Commands.Output;
public static class CommonResults
{
// sizeof says 1 byte for the empty types (i'm guessing type marker or pointer padding)
// aaaa i'm having withdrawals i miss rust enums

/// <summary>Indicates that the command was executed successfully.</summary>
public readonly record struct OKResult;

/// <summary>
/// Mostly for internal use; shows usage information to the user.<br/>
/// This must <b>never</b> be returned from a redeem.
/// </summary>
public readonly record struct ShowUsageResult;
public readonly record struct ErrorResult(string message);
// aaaa i'm having withdrawals i miss rust enums

/// <summary>
/// An internal error occurred while trying to execute the command.
/// </summary>
public readonly record struct ExceptionResult(Exception Exception);

/// <summary>
/// Something went wrong and the command could not be executed cleanly.
/// </summary>
/// <param name="message">Message to return to the user. Will be logged on the backend, as well as posting a notification on Discord.</param>
public readonly record struct ErrorResult(string message);

// no MessageResult(string) because you can just return a string (may still add one in the future for log levels and such)

/// <summary>
/// Acts like <see cref="ErrorResult"/> in that the user is shown an error and the redeem gets refunded;<br/>
/// The difference is that this does not trigger Discord logs.
/// </summary>
/// <param name="reason">Message to display to the user. This will be logged to the database but will not notify on Discord.</param>
public readonly record struct DenyResult(string reason);

public static OKResult OK() => new();
/// <summary>
/// The parameters supplied to the command were incorrect.<br/>
/// Do <b>not</b> return this from a redeem.
/// </summary>
public static ShowUsageResult ShowUsage() => new();
public static ErrorResult Error(string message) => new(message);
/// <summary>
/// Commands automatically catch exceptions but you can still use this.
/// </summary>
public static ExceptionResult Exception(Exception e) => new(e);
/// <summary>
/// The command failed to execute due to an error.
/// </summary>
/// <param name="message">The message to return to the user.</param>
public static ErrorResult Error(string message) => new(message);
/// <summary>
/// The command could not be executed due to a precondition (such as a cooldown).
/// </summary>
/// <param name="reason">Message to return to the user.</param>
public static DenyResult Deny(string reason) => new(reason);
}
3 changes: 1 addition & 2 deletions SCHIZO/Jukebox/CustomJukeboxTrackPatches.BelowZero.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Reflection.Emit;
using FMOD;
Expand Down Expand Up @@ -268,7 +267,7 @@ public static void OnSwitchingTracks(JukeboxInstance __instance)
__instance.SetPositionKnobVisible(!__instance.IsPlayingStream(out _));
}

//[HarmonyPatch(typeof(File), nameof(File.Exists))]
//[HarmonyPatch(typeof(System.IO.File), nameof(System.IO.File.Exists))]
//[HarmonyPostfix]
public static void DebugStuff(string path)
{
Expand Down
21 changes: 12 additions & 9 deletions SCHIZO/SwarmControl/MessageProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ private void OnRedeem(RedeemMessage msg)
if (!CommandRegistry.TryGetInnermostCommand(msg.Command.SplitOnce(' ').Before, out Command command))
{
LOGGER.LogDebug($"{msg.GetUsername()} tried to redeem unknown command \"{msg.Command}\"");
SendResult(guid, false, "Command not found");
SendResult(guid, ResultMessage.ResultKind.Error, "Command not found");
return;
}
// prevents server replaying redeems in case we receive one but the game doesn't acknowledge it or something (so the server thinks it didn't send and replays it later)
Expand Down Expand Up @@ -117,25 +117,28 @@ private void OnRedeem(RedeemMessage msg)
switch (ctx.Result)
{
case CommonResults.ErrorResult { message: string error }:
SendResult(msg.Guid, false, error);
SendResult(msg.Guid, ResultMessage.ResultKind.Error, error);
break;
case CommonResults.DenyResult { reason: string reason }:
SendResult(msg.Guid, ResultMessage.ResultKind.Deny, reason);
break;
case null or CommonResults.OKResult:
SendResult(msg.Guid, true);
SendResult(msg.Guid, ResultMessage.ResultKind.Success);
break;
case CommonResults.ExceptionResult { Exception: Exception e }:
SendResult(msg.Guid, false, e.ToString());
SendResult(msg.Guid, ResultMessage.ResultKind.Error, e.ToString());
break;
case CommonResults.ShowUsageResult:
SendResult(msg.Guid, false, $"Incorrect command usage - {ShowUsage.GetUsageString(command)}");
SendResult(msg.Guid, ResultMessage.ResultKind.Error, $"Incorrect command usage - {ShowUsage.GetUsageString(command)}");
break;
default:
SendResult(msg.Guid, true, ctx.Result.ToString());
SendResult(msg.Guid, ResultMessage.ResultKind.Success, ctx.Result.ToString());
break;
}
}
catch (Exception e)
{
SendResult(msg.Guid, false, e.ToString());
SendResult(msg.Guid, ResultMessage.ResultKind.Error, e.ToString());
}
});
}
Expand All @@ -148,12 +151,12 @@ private void SendHello()
});
}

private void SendResult(Guid guid, bool success, string? message = null)
private void SendResult(Guid guid, ResultMessage.ResultKind kind, string? message = null)
{
ResultMessage msg = new()
{
Guid = guid,
Success = success,
Status = kind,
Message = message
};
_results[msg.Guid] = msg;
Expand Down
5 changes: 1 addition & 4 deletions SCHIZO/SwarmControl/Models/Game/Messages/HelloBackMessage.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
using System.Diagnostics.CodeAnalysis;

namespace SwarmControl.Models.Game.Messages;

[method: SetsRequiredMembers]
public sealed record HelloBackMessage() : BackendMessage()
public sealed record HelloBackMessage : BackendMessage
{
public override MessageType MessageType => MessageType.HelloBack;
public bool Allowed { get; init; }
Expand Down
4 changes: 1 addition & 3 deletions SCHIZO/SwarmControl/Models/Game/Messages/RedeemMessage.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;

namespace SwarmControl.Models.Game.Messages;

#nullable enable
[method: SetsRequiredMembers]
public sealed record RedeemMessage() : BackendMessage()
public sealed record RedeemMessage : BackendMessage
{
public override MessageType MessageType => MessageType.Redeem;

Expand Down
24 changes: 20 additions & 4 deletions SCHIZO/SwarmControl/Models/Game/Messages/ResultMessage.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,28 @@
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;

namespace SwarmControl.Models.Game.Messages;

#nullable enable
[method: SetsRequiredMembers]
public sealed record ResultMessage() : GameMessage()
public sealed record ResultMessage : GameMessage
{
[JsonConverter(typeof(StringEnumConverter))]
public enum ResultKind
{
/// <summary>The redeem succeeded.</summary>
[EnumMember(Value = "success")]
Success,
/// <summary>The redeem failed to execute. The user should be notified (and refunded), and the backend should send a Discord notification.</summary>
[EnumMember(Value = "error")]
Error,
/// <summary>The redeem did not execute due to a precondition. The user is still refunded, but there is no need to ping in Discord.</summary>
[EnumMember(Value = "deny")]
Deny,
}
public override MessageType MessageType => MessageType.Result;
public bool Success { get; set; }
[JsonProperty(NamingStrategyType = typeof(CamelCaseNamingStrategy), Required = Required.Always)]
public ResultKind Status { get; set; }
public string? Message { get; set; }
}
16 changes: 12 additions & 4 deletions SCHIZO/SwarmControl/Models/Game/Messages/TwitchUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,15 @@ namespace SwarmControl.Models.Game.Messages;
/// <summary>
/// Twitch user info.
/// </summary>
/// <param name="Id">Channel ID.</param>
/// <param name="Login">Username/channel name.</param>
/// <param name="DisplayName">What's displayed in chat.</param>
public record TwitchUser(string Id, string Login, string DisplayName);
/// <param name="id">Channel ID.</param>
/// <param name="login">Username/channel name.</param>
/// <param name="displayName">The name you see in chat.</param>
public class TwitchUser(string id, string? login = null, string? displayName = null)
{
/// <summary>Twitch's internal channel ID that corresponds to this user.</summary>
public string Id { get; } = id;
/// <summary>Username/channel name.</summary>
public string Login { get; } = login ?? id;
/// <summary>The name displayed in chat.</summary>
public string DisplayName { get; } = displayName ?? login ?? id;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ internal class DetachBackSeatruckModule : Command, IParameters

protected override object? ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main) return CommonResults.Error("Requires a loaded game.");
if (!Player.main) return CommonResults.Deny("Requires a loaded game.");

SeaTruckUpgrades cabin = GameObject.FindObjectOfType<SeaTruckUpgrades>();
if (!cabin) return CommonResults.Error("Sea Truck not found.");
if (!cabin) return CommonResults.Deny("Sea Truck not found.");

SeaTruckSegment cabinSegment = cabin.GetComponent<SeaTruckSegment>();
SeaTruckSegment rearSegment = cabinSegment;
while (rearSegment.rearConnection && rearSegment.rearConnection.connection)
rearSegment = rearSegment.rearConnection.connection.truckSegment;

if (rearSegment == cabinSegment)
return CommonResults.Error("Sea Truck not connected to any modules.");
return CommonResults.Deny("Sea Truck is not connected to any modules.");

rearSegment.Detach();

Expand Down
2 changes: 1 addition & 1 deletion SCHIZO/SwarmControl/Redeems/Annoying/FlipPDA.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public enum Direction

protected override object ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main) return CommonResults.Error("Requires a loaded game.");
if (!Player.main) return CommonResults.Deny("Requires a loaded game.");

PDA pda = Player.main.GetPDA();
if (!pda) return CommonResults.Error("Could not get PDA."); // should never ever ever happen
Expand Down
2 changes: 1 addition & 1 deletion SCHIZO/SwarmControl/Redeems/Annoying/FloodBaseRedeem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ internal class FloodBaseRedeem() : ProxyCommand<FloodBase>("damagebase")
public override IReadOnlyList<Parameter> Parameters => [];
protected override object? ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main) return CommonResults.Error("Requires a loaded game");
if (!Player.main) return CommonResults.Deny("Requires a loaded game");

return base.ExecuteCore(ctx);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@

namespace SCHIZO.SwarmControl.Redeems.Annoying;

[System.Obsolete("This was only ever going to be funny for one stream", true)]
[Redeem(
Name = "redeem_scanrandomfragment",
DisplayName = "Scan Random Fragment",
Description = "Auto-scans a random fragment, chosen by fair dice roll."
Description = "Auto-scans a random fragment, chosen by fair dice roll.",
Export = false
)]
internal class ScanTotallyRandomFragment : Command, IParameters
{
Expand Down
2 changes: 1 addition & 1 deletion SCHIZO/SwarmControl/Redeems/Annoying/ShowCaptcha.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ internal class ShowCaptcha : Command, IParameters

protected override object? ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main) return CommonResults.Error("Requires a loaded game.");
if (!Player.main) return CommonResults.Deny("Requires a loaded game.");
if (!Captcha.Instance) return CommonResults.Error("Captcha not found.");

CoroutineHost.StartCoroutine(Coro());
Expand Down
3 changes: 2 additions & 1 deletion SCHIZO/SwarmControl/Redeems/Annoying/ShowNotif.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ namespace SCHIZO.SwarmControl.Redeems.Annoying;
[Redeem(
Name = "redeem_notif",
DisplayName = "Ping Alex",
Description = "This will log an error on the backend, pinging Alex for no reason"
Description = "This will log an error on the backend, pinging Alex for no reason",
Export = false
)]
internal class ShowNotif : Command, IParameters
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ internal class SpinHimAround : Command, IParameters

protected override object ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main) return CommonResults.Error("Requires a loaded game.");
if (!Player.main) return CommonResults.Deny("Requires a loaded game.");

Player.main.lilyPaddlerHypnosis.StartHypnosis(DayNightCycle.main.timePassed);
CoroutineHost.StartCoroutine(Coro());
Expand Down
3 changes: 2 additions & 1 deletion SCHIZO/SwarmControl/Redeems/Audio/PlayNoise.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace SCHIZO.SwarmControl.Redeems.Audio;
[Redeem(
Name = "redeem_noise",
DisplayName = "Play Sound",
Announce = false
Announce = false,
Export = false
)]
internal class PlayNoise : Command, IParameters
{
Expand Down
3 changes: 2 additions & 1 deletion SCHIZO/SwarmControl/Redeems/Audio/PlayTrollNoise.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ namespace SCHIZO.SwarmControl.Redeems.Audio;
Name = "redeem_trollnoise",
DisplayName = "Play Troll Sound",
Description = "IMPORTANT: Leviathan sound will not play if not underwater",
Announce = false
Announce = false,
Export = false
)]
internal class PlayTrollNoise : Command, IParameters
{
Expand Down
4 changes: 2 additions & 2 deletions SCHIZO/SwarmControl/Redeems/Helpful/SaveGame.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ protected override object ExecuteCore(CommandExecutionContext ctx)
_lastSave = PDA.time;
return CommonResults.OK();
}
else // yoink money from spammers
else
{
return "Last save was less than a minute ago. Rest assured the game is saved.";
return CommonResults.Deny("Last save was less than a minute ago. You will be credited back for this redeem.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ internal class SeaMonkeyDeliverySystem : Command, IParameters

protected override object ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main) return CommonResults.Error("Requires a loaded game");
if (!Player.main) return CommonResults.Deny("Requires a loaded game");

TechType item;
try
Expand Down
5 changes: 3 additions & 2 deletions SCHIZO/SwarmControl/Redeems/Misc/BigErm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@
namespace SCHIZO.SwarmControl.Redeems.Misc;

#nullable enable
[Redeem(Name = "redeem_bigerm",
[Redeem(
Name = "redeem_bigerm",
DisplayName = "Big Erm",
Description = "The Erm Moon sends its regards"
Description = "Convert a nearby ermfish to be Big. The Erm Moon sends its regards"
)]
internal class BigErm : Command, IParameters
{
Expand Down
2 changes: 2 additions & 0 deletions SCHIZO/SwarmControl/Redeems/Misc/Floaties.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public Floaties()

protected override object ExecuteCore(CommandExecutionContext ctx)
{
if (!Player.main.IsUnderwaterForSwimming())
return CommonResults.Deny("Player must be swimming underwater");
_timer.AddTime(Duration);
_timer.Start();
return CommonResults.OK();
Expand Down
5 changes: 3 additions & 2 deletions SCHIZO/SwarmControl/Redeems/Misc/MidasTouch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace SCHIZO.SwarmControl.Redeems.Misc;
[Redeem(
Name = "redeem_midas",
DisplayName = "Midas' Touch",
Description = "And all that glitters is gold"
Description = "And all that glitters is gold",
Export = false
)]
public sealed class MidasTouch : Command, IParameters
{
Expand Down Expand Up @@ -67,7 +68,7 @@ protected override object ExecuteCore(CommandExecutionContext ctx)
.ToArray();
if (items.Length == 0)
{
return CommonResults.Error("No items to turn");
return CommonResults.Deny("No items to turn");
}
foreach (InventoryItem item in items)
{
Expand Down

0 comments on commit 553f105

Please sign in to comment.