ColourBreakBugReportStore.cs

Local storage for ColourBreak bug reports. It reads and writes a ColourBreakBugReportLog to Game.Cookies, enforces max counts and message length, and provides helpers to add, list, mark resolved, delete, and clear reports.

File Access
using Sandbox;
using System;
using System.Linq;
using System.Collections.Generic;

// Local persistence for bug reports, stored in a cookie like the progress store.
// No network calls — the dev reads them in-game via the hidden manager.
public static class ColourBreakBugReportStore
{
	const string CookieKey = "colourbreak.bugreports.v1";
	const int MaxReports = 200;
	const int MaxMessageLength = 600;

	public static ColourBreakBugReportLog Load()
	{
		try
		{
			return Game.Cookies.Get( CookieKey, new ColourBreakBugReportLog() ) ?? new ColourBreakBugReportLog();
		}
		catch ( Exception e )
		{
			Log.Warning( $"Could not load bug reports: {e.Message}" );
			return new ColourBreakBugReportLog();
		}
	}

	public static void Save( ColourBreakBugReportLog log )
	{
		if ( log == null ) return;
		try
		{
			Game.Cookies.Set( CookieKey, log );
		}
		catch ( Exception e )
		{
			Log.Warning( $"Could not save bug reports: {e.Message}" );
		}
	}

	public static List<ColourBreakBugReport> GetAll()
	{
		return Load().Reports ?? new List<ColourBreakBugReport>();
	}

	public static int OpenCount()
	{
		return GetAll().Count( r => r != null && !r.Resolved );
	}

	public static bool Add( ColourBreakBugReport report )
	{
		if ( report == null )
			return false;

		report.Message = (report.Message ?? "").Trim();
		if ( string.IsNullOrWhiteSpace( report.Message ) )
			return false;

		if ( report.Message.Length > MaxMessageLength )
			report.Message = report.Message.Substring( 0, MaxMessageLength );

		var log = Load();
		log.Reports ??= new List<ColourBreakBugReport>();
		log.Reports.Insert( 0, report );   // newest first
		if ( log.Reports.Count > MaxReports )
			log.Reports.RemoveRange( MaxReports, log.Reports.Count - MaxReports );

		Save( log );
		return true;
	}

	public static void SetResolved( string id, bool resolved )
	{
		var log = Load();
		var r = log.Reports?.FirstOrDefault( x => x != null && x.Id == id );
		if ( r == null ) return;
		r.Resolved = resolved;
		Save( log );
	}

	public static void Delete( string id )
	{
		var log = Load();
		log.Reports?.RemoveAll( x => x == null || x.Id == id );
		Save( log );
	}

	public static void Clear()
	{
		Save( new ColourBreakBugReportLog() );
	}
}