diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index f9d0cce..395bdbf 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -6,14 +6,34 @@ on: jobs: build: runs-on: ubuntu-latest - + env: Solution_Name: ReplayBrowser.sln - + + services: + postgres: + image: postgres:latest + env: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: ReplayBrowser + ports: + - 5432:5432 + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + steps: + # SETUP + - name: Checkout uses: actions/checkout@v3 + - name: Seed database + run: PGPASSWORD='postgres' psql -h localhost -U postgres -d ReplayBrowser -f ./Tools/replaybrowser_ci_seed.sql + - name: Install .NET Core uses: actions/setup-dotnet@v3 with: @@ -22,8 +42,38 @@ jobs: - name: Verify .NET Core version run: dotnet --version + - name: Install dotnet-ef + run: dotnet tool install --global dotnet-ef + + - name: Verify dotnet-ef version + run: dotnet ef --version + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.x' + + - name: Install python dependencies + run: | + python -m pip install --upgrade pip + pip install pyppeteer + - name: Restore NuGet Packages run: dotnet restore ./ReplayBrowser/ReplayBrowser.csproj + - name: Write appsettings.Secret.json file # This file is used to store the connection string for the database + run: echo "{\"ConnectionStrings\":{\"DefaultConnection\":\"Host=localhost;Port=5432;Database=ReplayBrowser;Username=postgres;Password=postgres\"}}" > ./ReplayBrowser/appsettings.Secret.json + + # BUILD AND TEST + - name: Build Solution - run: dotnet build ./ReplayBrowser/ReplayBrowser.csproj \ No newline at end of file + run: dotnet build ./ReplayBrowser/ReplayBrowser.csproj --no-restore --configuration Testing + + - name: Check pending migrations + run: python ./Tools/check_model_pending_changes.py # Exits with 1 if there are pending migrations + + - name: Run Migrations + run: dotnet ef database update --project ./ReplayBrowser/ReplayBrowser.csproj --no-build --verbose + + - name: Run Tests + run: python ./Tools/test_pages_for_errors.py \ No newline at end of file diff --git a/ReplayBrowser.sln b/ReplayBrowser.sln index 2c816dd..3b7c773 100644 --- a/ReplayBrowser.sln +++ b/ReplayBrowser.sln @@ -6,10 +6,13 @@ Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU + Testing|Any CPU = Testing|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {C1E45DF7-3B40-4B1C-9966-35D4C666A735}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C1E45DF7-3B40-4B1C-9966-35D4C666A735}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C1E45DF7-3B40-4B1C-9966-35D4C666A735}.Testing|Any CPU.ActiveCfg = Testing|Any CPU + {C1E45DF7-3B40-4B1C-9966-35D4C666A735}.Testing|Any CPU.Build.0 = Testing|Any CPU {C1E45DF7-3B40-4B1C-9966-35D4C666A735}.Release|Any CPU.ActiveCfg = Release|Any CPU {C1E45DF7-3B40-4B1C-9966-35D4C666A735}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection diff --git a/ReplayBrowser/Controllers/ReplayController.cs b/ReplayBrowser/Controllers/ReplayController.cs index c8090d2..21efb8c 100644 --- a/ReplayBrowser/Controllers/ReplayController.cs +++ b/ReplayBrowser/Controllers/ReplayController.cs @@ -6,6 +6,7 @@ using ReplayBrowser.Data.Models; using ReplayBrowser.Helpers; using ReplayBrowser.Services; +using ReplayBrowser.Services.ReplayParser; namespace ReplayBrowser.Controllers; @@ -17,12 +18,14 @@ public class ReplayController : Controller private readonly ReplayDbContext _dbContext; private readonly AccountService _accountService; private readonly ReplayHelper _replayHelper; + private readonly ReplayParserService _replayParserService; - public ReplayController(ReplayDbContext dbContext, AccountService accountService, ReplayHelper replayHelper) + public ReplayController(ReplayDbContext dbContext, AccountService accountService, ReplayHelper replayHelper, ReplayParserService replayParserService) { _dbContext = dbContext; _accountService = accountService; _replayHelper = replayHelper; + _replayParserService = replayParserService; } [HttpGet("{replayId}")] @@ -39,6 +42,42 @@ public async Task GetReplay(int replayId) return Ok(replay); } + /// + /// Tells the server to parse a replay based on a provided url. + /// + /// + [HttpPost("replay/parse")] + public async Task ParseReplay( + [FromQuery] string url + ) + { + if (User.Identity is null || !User.Identity.IsAuthenticated) + { + return Unauthorized(); + } + + var guidRequestor = AccountHelper.GetAccountGuid(User); + + var requestor = await _dbContext.Accounts + .Include(a => a.Settings) + .Include(a => a.History) + .FirstOrDefaultAsync(a => a.Guid == guidRequestor); + + if (requestor == null) + { + return NotFound("Account is null. This should not happen."); + } + + if (!requestor.IsAdmin) + return Unauthorized("You are not an admin."); + + ReplayParserService.Queue.Add(url); + if (_replayParserService.RequestQueueConsumption()) + return Ok(); + + return BadRequest("The replay parser is currently busy."); + } + /// /// Deletes all stored profiles for a server group. /// diff --git a/ReplayBrowser/Data/Migrations/20240826004046_HistoryEntryForeignKeys.Designer.cs b/ReplayBrowser/Data/Migrations/20240826004046_HistoryEntryForeignKeys.Designer.cs new file mode 100644 index 0000000..ac346f3 --- /dev/null +++ b/ReplayBrowser/Data/Migrations/20240826004046_HistoryEntryForeignKeys.Designer.cs @@ -0,0 +1,556 @@ +// +using System; +using System.Collections.Generic; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +using NpgsqlTypes; +using ReplayBrowser.Data; + +#nullable disable + +namespace Server.Migrations +{ + [DbContext(typeof(ReplayDbContext))] + [Migration("20240826004046_HistoryEntryForeignKeys")] + partial class HistoryEntryForeignKeys + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.2") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Account.Account", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property>("FavoriteReplays") + .IsRequired() + .HasColumnType("integer[]"); + + b.Property("Guid") + .HasColumnType("uuid"); + + b.Property("IsAdmin") + .HasColumnType("boolean"); + + b.Property("Protected") + .HasColumnType("boolean"); + + b.Property>("SavedProfiles") + .IsRequired() + .HasColumnType("uuid[]"); + + b.Property("SettingsId") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Guid") + .IsUnique(); + + b.HasIndex("SettingsId"); + + b.HasIndex("Username"); + + b.ToTable("Accounts"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Account.AccountSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property>("Friends") + .IsRequired() + .HasColumnType("uuid[]"); + + b.Property("RedactInformation") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.ToTable("AccountSettings"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Account.HistoryEntry", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer"); + + b.Property("Action") + .IsRequired() + .HasColumnType("text"); + + b.Property("Details") + .HasColumnType("text"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.ToTable("HistoryEntry"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.CharacterData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text"); + + b.Property("CollectedPlayerDataPlayerGuid") + .HasColumnType("uuid"); + + b.Property("LastPlayed") + .HasColumnType("timestamp with time zone"); + + b.Property("RoundsPlayed") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CollectedPlayerDataPlayerGuid"); + + b.ToTable("CharacterData"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.CollectedPlayerData", b => + { + b.Property("PlayerGuid") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("GeneratedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("IsWatched") + .HasColumnType("boolean"); + + b.Property("LastSeen") + .HasColumnType("timestamp with time zone"); + + b.Property("PlayerDataId") + .HasColumnType("integer"); + + b.Property("TotalAntagRoundsPlayed") + .HasColumnType("integer"); + + b.Property("TotalEstimatedPlaytime") + .HasColumnType("interval"); + + b.Property("TotalRoundsPlayed") + .HasColumnType("integer"); + + b.HasKey("PlayerGuid"); + + b.HasIndex("PlayerDataId"); + + b.HasIndex("PlayerGuid") + .IsUnique(); + + b.ToTable("PlayerProfiles"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.GdprRequest", b => + { + b.Property("Guid") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.HasKey("Guid"); + + b.ToTable("GdprRequests"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.JobCountData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CollectedPlayerDataPlayerGuid") + .HasColumnType("uuid"); + + b.Property("JobPrototype") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastPlayed") + .HasColumnType("timestamp with time zone"); + + b.Property("RoundsPlayed") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("CollectedPlayerDataPlayerGuid"); + + b.ToTable("JobCountData"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.JobDepartment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Department") + .IsRequired() + .HasColumnType("text"); + + b.Property("Job") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Job") + .IsUnique(); + + b.ToTable("JobDepartments"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Notice", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("EndDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Message") + .IsRequired() + .HasColumnType("text"); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Title") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Notices"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.ParsedReplay", b => + { + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Name"); + + b.ToTable("ParsedReplays"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Antag") + .HasColumnType("boolean"); + + b.Property>("AntagPrototypes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("EffectiveJobId") + .HasColumnType("integer"); + + b.Property>("JobPrototypes") + .IsRequired() + .HasColumnType("text[]"); + + b.Property("ParticipantId") + .HasColumnType("integer"); + + b.Property("PlayerIcName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("EffectiveJobId"); + + b.HasIndex("ParticipantId"); + + b.HasIndex("PlayerIcName"); + + b.ToTable("Players"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.PlayerData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PlayerGuid") + .HasColumnType("uuid"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("PlayerData"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Replay", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("timestamp with time zone"); + + b.Property("Duration") + .IsRequired() + .HasColumnType("text"); + + b.Property("EndTick") + .HasColumnType("integer"); + + b.Property("EndTime") + .IsRequired() + .HasColumnType("text"); + + b.Property("FileCount") + .HasColumnType("integer"); + + b.Property("Gamemode") + .IsRequired() + .HasColumnType("text"); + + b.Property("Link") + .IsRequired() + .HasColumnType("text"); + + b.Property("Map") + .HasColumnType("text"); + + b.Property>("Maps") + .HasColumnType("text[]"); + + b.Property("RoundEndText") + .HasColumnType("text"); + + b.Property("RoundEndTextSearchVector") + .IsRequired() + .ValueGeneratedOnAddOrUpdate() + .HasColumnType("tsvector") + .HasAnnotation("Npgsql:TsVectorConfig", "english") + .HasAnnotation("Npgsql:TsVectorProperties", new[] { "RoundEndText" }); + + b.Property("RoundId") + .HasColumnType("integer"); + + b.Property("ServerId") + .IsRequired() + .HasColumnType("text"); + + b.Property("ServerName") + .HasColumnType("text"); + + b.Property("Size") + .HasColumnType("integer"); + + b.Property("UncompressedSize") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("Gamemode"); + + b.HasIndex("Map"); + + b.HasIndex("RoundEndTextSearchVector"); + + NpgsqlIndexBuilderExtensions.HasMethod(b.HasIndex("RoundEndTextSearchVector"), "GIN"); + + b.HasIndex("ServerId"); + + b.HasIndex("ServerName"); + + b.ToTable("Replays"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.ReplayParticipant", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("PlayerGuid") + .HasColumnType("uuid"); + + b.Property("ReplayId") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("ReplayId"); + + b.HasIndex("Username"); + + b.HasIndex("PlayerGuid", "ReplayId") + .IsUnique(); + + b.ToTable("ReplayParticipants"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Account.Account", b => + { + b.HasOne("ReplayBrowser.Data.Models.Account.AccountSettings", "Settings") + .WithMany() + .HasForeignKey("SettingsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Settings"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Account.HistoryEntry", b => + { + b.HasOne("ReplayBrowser.Data.Models.Account.Account", "Account") + .WithMany("History") + .HasForeignKey("AccountId"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.CharacterData", b => + { + b.HasOne("ReplayBrowser.Data.Models.CollectedPlayerData", null) + .WithMany("Characters") + .HasForeignKey("CollectedPlayerDataPlayerGuid"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.CollectedPlayerData", b => + { + b.HasOne("ReplayBrowser.Data.Models.PlayerData", "PlayerData") + .WithMany() + .HasForeignKey("PlayerDataId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("PlayerData"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.JobCountData", b => + { + b.HasOne("ReplayBrowser.Data.Models.CollectedPlayerData", null) + .WithMany("JobCount") + .HasForeignKey("CollectedPlayerDataPlayerGuid"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Player", b => + { + b.HasOne("ReplayBrowser.Data.Models.JobDepartment", "EffectiveJob") + .WithMany() + .HasForeignKey("EffectiveJobId"); + + b.HasOne("ReplayBrowser.Data.Models.ReplayParticipant", "Participant") + .WithMany("Players") + .HasForeignKey("ParticipantId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("EffectiveJob"); + + b.Navigation("Participant"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.ReplayParticipant", b => + { + b.HasOne("ReplayBrowser.Data.Models.Replay", "Replay") + .WithMany("RoundParticipants") + .HasForeignKey("ReplayId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Replay"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Account.Account", b => + { + b.Navigation("History"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.CollectedPlayerData", b => + { + b.Navigation("Characters"); + + b.Navigation("JobCount"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.Replay", b => + { + b.Navigation("RoundParticipants"); + }); + + modelBuilder.Entity("ReplayBrowser.Data.Models.ReplayParticipant", b => + { + b.Navigation("Players"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/ReplayBrowser/Data/Migrations/20240826004046_HistoryEntryForeignKeys.cs b/ReplayBrowser/Data/Migrations/20240826004046_HistoryEntryForeignKeys.cs new file mode 100644 index 0000000..0a21cde --- /dev/null +++ b/ReplayBrowser/Data/Migrations/20240826004046_HistoryEntryForeignKeys.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Server.Migrations +{ + /// + public partial class HistoryEntryForeignKeys : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/ReplayBrowser/Data/Migrations/ReplayDbContextModelSnapshot.cs b/ReplayBrowser/Data/Migrations/ReplayDbContextModelSnapshot.cs index 1a43a7e..48b9ef6 100644 --- a/ReplayBrowser/Data/Migrations/ReplayDbContextModelSnapshot.cs +++ b/ReplayBrowser/Data/Migrations/ReplayDbContextModelSnapshot.cs @@ -466,9 +466,11 @@ protected override void BuildModel(ModelBuilder modelBuilder) modelBuilder.Entity("ReplayBrowser.Data.Models.Account.HistoryEntry", b => { - b.HasOne("ReplayBrowser.Data.Models.Account.Account", null) + b.HasOne("ReplayBrowser.Data.Models.Account.Account", "Account") .WithMany("History") .HasForeignKey("AccountId"); + + b.Navigation("Account"); }); modelBuilder.Entity("ReplayBrowser.Data.Models.CharacterData", b => diff --git a/ReplayBrowser/Data/Models/Account/History.cs b/ReplayBrowser/Data/Models/Account/History.cs index 4f17e73..b23e8b7 100644 --- a/ReplayBrowser/Data/Models/Account/History.cs +++ b/ReplayBrowser/Data/Models/Account/History.cs @@ -8,8 +8,8 @@ public class HistoryEntry public DateTime Time { get; set; } public string? Details { get; set; } - public Account Account { get; set; } = null!; - public int AccountId { get; set; } + public Account? Account { get; set; } = null!; + public int? AccountId { get; set; } } public enum Action diff --git a/ReplayBrowser/Pages/Throw.razor b/ReplayBrowser/Pages/Throw.razor new file mode 100644 index 0000000..6ac3cc1 --- /dev/null +++ b/ReplayBrowser/Pages/Throw.razor @@ -0,0 +1,14 @@ +@page "/throw" + +

This page only works in TESTING and DEVELOPMENT environments

+ +@code { + protected override void OnInitialized() + { +#if RELEASE + return; +#endif + // This page is purposely throwing an exception. + throw new Exception("An error occurred"); + } +} \ No newline at end of file diff --git a/ReplayBrowser/Program.cs b/ReplayBrowser/Program.cs index 48d90d3..f12782d 100644 --- a/ReplayBrowser/Program.cs +++ b/ReplayBrowser/Program.cs @@ -1,3 +1,4 @@ +using System.Net; using ReplayBrowser.Services; using ReplayBrowser.Services.ReplayParser; using Serilog; @@ -37,6 +38,7 @@ public static IHostBuilder CreateHostBuilder(string[] args) => builder.AddJsonFile("appsettings.Secret.json", optional: true, reloadOnChange: true); builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true); builder.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); + builder.AddEnvironmentVariables(); }) .UseSerilog((ctx, cfg) => { @@ -50,7 +52,12 @@ public static IHostBuilder CreateHostBuilder(string[] args) => }) .ConfigureWebHostDefaults(webBuilder => { - webBuilder.UseKestrel(); + webBuilder.UseKestrel().ConfigureKestrel(o => + { +#if TESTING + o.Listen(IPAddress.Any, 5000); // HTTP +#endif + }); webBuilder.UseStartup(); }) .ConfigureServices(s => { diff --git a/ReplayBrowser/ReplayBrowser.csproj b/ReplayBrowser/ReplayBrowser.csproj index 9fdbee9..588aab4 100644 --- a/ReplayBrowser/ReplayBrowser.csproj +++ b/ReplayBrowser/ReplayBrowser.csproj @@ -4,6 +4,8 @@ net8.0 enable enable + Debug;Release;Testing + AnyCPU diff --git a/ReplayBrowser/Services/AccountService.cs b/ReplayBrowser/Services/AccountService.cs index eb911bb..7f8e7d1 100644 --- a/ReplayBrowser/Services/AccountService.cs +++ b/ReplayBrowser/Services/AccountService.cs @@ -201,9 +201,9 @@ public async Task UpdateAccount(Account? account) var historyQuery = context.Set().AsQueryable(); if (string.IsNullOrWhiteSpace(username)) - historyQuery = historyQuery.Where(h => h.Account.Guid == Guid.Empty); + historyQuery = historyQuery.Where(h => h.AccountId == null || h.Account!.Guid == Guid.Empty); else - historyQuery = historyQuery.Where(h => h.Account.Username == username); + historyQuery = historyQuery.Where(h => h.Account!.Username == username); var totalCount = await historyQuery.CountAsync(); diff --git a/ReplayBrowser/Services/ReplayParser/ReplayParserService.cs b/ReplayBrowser/Services/ReplayParser/ReplayParserService.cs index e069ae6..b56b6fe 100644 --- a/ReplayBrowser/Services/ReplayParser/ReplayParserService.cs +++ b/ReplayBrowser/Services/ReplayParser/ReplayParserService.cs @@ -49,8 +49,10 @@ public Task StartAsync(CancellationToken cancellationToken) } Status = ParserStatus.Idle; - + +#if !TESTING Task.Run(() => FetchReplays(TokenSource.Token, urLs), TokenSource.Token); +#endif return Task.CompletedTask; } @@ -101,6 +103,18 @@ private async Task FetchReplays(CancellationToken token, StorageUrl[] storageUrl } } + /// + /// Requests the queue to be consumed. It will only consume the queue if it's not already being consumed. + /// + public bool RequestQueueConsumption() + { + if (Status != ParserStatus.Idle) return false; + + + Task.Run(() => ConsumeQueue(TokenSource.Token), TokenSource.Token); + return true; + } + private async Task ConsumeQueue(CancellationToken token) { if (Queue.Count > 0) @@ -212,6 +226,11 @@ private async Task ConsumeQueue(CancellationToken token) Log.Warning("Parsing took too long for " + string.Join(", ", tasks.Select(x => x.Id))); } } + + // Set the status to idle. + Status = ParserStatus.Idle; + Details = ""; + Log.Information("Finished parsing replays."); } /// diff --git a/ReplayBrowser/Startup.cs b/ReplayBrowser/Startup.cs index dfd4f57..fe0e014 100644 --- a/ReplayBrowser/Startup.cs +++ b/ReplayBrowser/Startup.cs @@ -84,8 +84,8 @@ public void ConfigureServices(IServiceCollection services) var proxyIP = Configuration["ProxyIP"]; if (proxyIP == null) { - Log.Fatal("No proxy IP found in appsettings.json. Exiting."); - Environment.Exit(1); + proxyIP = "127.0.10.1"; + Log.Warning("No ProxyIP set in configuration. Defaulting to {ProxyIP}", proxyIP); } Log.Information("Proxy IP: {ProxyIP}", proxyIP); @@ -167,6 +167,7 @@ public void ConfigureServices(IServiceCollection services) JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); + #if !TESTING services.AddAuthentication(options => { options.DefaultScheme = "Cookies"; @@ -190,6 +191,8 @@ public void ConfigureServices(IServiceCollection services) options.GetClaimsFromUserInfoEndpoint = true; }); + #endif + services.AddHttpLogging(o => { }); @@ -241,7 +244,9 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) #endif app.UseStatusCodePagesWithReExecute("/error/{0}"); +#if !TESTING app.UseHttpsRedirection(); +#endif app.UseStaticFiles(); diff --git a/Tools/check_model_pending_changes.py b/Tools/check_model_pending_changes.py new file mode 100644 index 0000000..3b6034c --- /dev/null +++ b/Tools/check_model_pending_changes.py @@ -0,0 +1,30 @@ +# This script checks if there are any pending changes in the model and if so, it will fail. +# This is useful to prevent committing changes to the model that are not intended. + +import subprocess +import sys + +def main(): + try: + # Run the dotnet ef migrations has-pending-model-changes command + result = subprocess.run( + ['dotnet', 'ef', 'migrations', 'has-pending-model-changes', '--project', './ReplayBrowser/ReplayBrowser.csproj'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + text=True + ) + + # Check the output and return code + if result.returncode == 0: + print("No pending model changes detected.") + else: + print("Pending model changes detected:") + print(result.stdout) + sys.exit(1) + + except Exception as e: + print(f"An error occurred while checking for pending migrations: {str(e)}") + sys.exit(1) + +if __name__ == '__main__': + main() \ No newline at end of file diff --git a/Tools/replaybrowser_ci_seed.sql b/Tools/replaybrowser_ci_seed.sql new file mode 100644 index 0000000..e69594c --- /dev/null +++ b/Tools/replaybrowser_ci_seed.sql @@ -0,0 +1,1746 @@ +-- +-- PostgreSQL database dump +-- + +-- Dumped from database version 16.1 +-- Dumped by pg_dump version 16.4 + +-- Started on 2024-08-26 03:37:01 + +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; + +SET default_tablespace = ''; + +SET default_table_access_method = heap; + +-- +-- TOC entry 222 (class 1259 OID 30099) +-- Name: AccountSettings; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."AccountSettings" ( + "Id" integer NOT NULL, + "RedactInformation" boolean NOT NULL, + "Friends" uuid[] NOT NULL +); + + +ALTER TABLE public."AccountSettings" OWNER TO postgres; + +-- +-- TOC entry 221 (class 1259 OID 30098) +-- Name: AccountSettings_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."AccountSettings" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."AccountSettings_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 224 (class 1259 OID 30107) +-- Name: Accounts; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."Accounts" ( + "Id" integer NOT NULL, + "Guid" uuid NOT NULL, + "Username" text NOT NULL, + "IsAdmin" boolean NOT NULL, + "SettingsId" integer NOT NULL, + "FavoriteReplays" integer[] DEFAULT ARRAY[]::integer[] NOT NULL, + "SavedProfiles" uuid[] DEFAULT ARRAY[]::uuid[] NOT NULL, + "Protected" boolean DEFAULT false NOT NULL +); + + +ALTER TABLE public."Accounts" OWNER TO postgres; + +-- +-- TOC entry 223 (class 1259 OID 30106) +-- Name: Accounts_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."Accounts" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."Accounts_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 234 (class 1259 OID 30171) +-- Name: CharacterData; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."CharacterData" ( + "Id" integer NOT NULL, + "CollectedPlayerDataPlayerGuid" uuid, + "CharacterName" text NOT NULL, + "LastPlayed" timestamp with time zone NOT NULL, + "RoundsPlayed" integer NOT NULL +); + + +ALTER TABLE public."CharacterData" OWNER TO postgres; + +-- +-- TOC entry 233 (class 1259 OID 30170) +-- Name: CharacterData_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."CharacterData" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."CharacterData_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 227 (class 1259 OID 30138) +-- Name: GdprRequests; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."GdprRequests" ( + "Guid" uuid NOT NULL +); + + +ALTER TABLE public."GdprRequests" OWNER TO postgres; + +-- +-- TOC entry 226 (class 1259 OID 30120) +-- Name: HistoryEntry; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."HistoryEntry" ( + "Id" integer NOT NULL, + "Action" text NOT NULL, + "Time" timestamp with time zone NOT NULL, + "Details" text, + "AccountId" integer +); + + +ALTER TABLE public."HistoryEntry" OWNER TO postgres; + +-- +-- TOC entry 225 (class 1259 OID 30119) +-- Name: HistoryEntry_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."HistoryEntry" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."HistoryEntry_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 236 (class 1259 OID 30184) +-- Name: JobCountData; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."JobCountData" ( + "Id" integer NOT NULL, + "CollectedPlayerDataPlayerGuid" uuid, + "JobPrototype" text NOT NULL, + "RoundsPlayed" integer NOT NULL, + "LastPlayed" timestamp with time zone NOT NULL +); + + +ALTER TABLE public."JobCountData" OWNER TO postgres; + +-- +-- TOC entry 235 (class 1259 OID 30183) +-- Name: JobCountData_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."JobCountData" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."JobCountData_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 238 (class 1259 OID 30202) +-- Name: JobDepartments; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."JobDepartments" ( + "Id" integer NOT NULL, + "Job" text NOT NULL, + "Department" text NOT NULL +); + + +ALTER TABLE public."JobDepartments" OWNER TO postgres; + +-- +-- TOC entry 237 (class 1259 OID 30201) +-- Name: JobDepartments_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."JobDepartments" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."JobDepartments_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 229 (class 1259 OID 30144) +-- Name: Notices; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."Notices" ( + "Id" integer NOT NULL, + "Title" text NOT NULL, + "Message" text NOT NULL, + "StartDate" timestamp with time zone NOT NULL, + "EndDate" timestamp with time zone NOT NULL +); + + +ALTER TABLE public."Notices" OWNER TO postgres; + +-- +-- TOC entry 228 (class 1259 OID 30143) +-- Name: Notices_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."Notices" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."Notices_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 220 (class 1259 OID 30071) +-- Name: ParsedReplays; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."ParsedReplays" ( + "Name" text NOT NULL +); + + +ALTER TABLE public."ParsedReplays" OWNER TO postgres; + +-- +-- TOC entry 231 (class 1259 OID 30153) +-- Name: PlayerData; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."PlayerData" ( + "Id" integer NOT NULL, + "PlayerGuid" uuid, + "Username" text NOT NULL +); + + +ALTER TABLE public."PlayerData" OWNER TO postgres; + +-- +-- TOC entry 230 (class 1259 OID 30152) +-- Name: PlayerData_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."PlayerData" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."PlayerData_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 232 (class 1259 OID 30160) +-- Name: PlayerProfiles; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."PlayerProfiles" ( + "PlayerGuid" uuid NOT NULL, + "GeneratedAt" timestamp with time zone NOT NULL, + "PlayerDataId" integer NOT NULL, + "TotalEstimatedPlaytime" interval NOT NULL, + "TotalRoundsPlayed" integer NOT NULL, + "TotalAntagRoundsPlayed" integer NOT NULL, + "LastSeen" timestamp with time zone NOT NULL, + "IsWatched" boolean NOT NULL +); + + +ALTER TABLE public."PlayerProfiles" OWNER TO postgres; + +-- +-- TOC entry 219 (class 1259 OID 30058) +-- Name: Players; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."Players" ( + "Id" integer NOT NULL, + "AntagPrototypes" text[] NOT NULL, + "JobPrototypes" text[] NOT NULL, + "PlayerIcName" text NOT NULL, + "Antag" boolean NOT NULL, + "ParticipantId" integer DEFAULT 0 NOT NULL, + "EffectiveJobId" integer +); + + +ALTER TABLE public."Players" OWNER TO postgres; + +-- +-- TOC entry 218 (class 1259 OID 30057) +-- Name: Players_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."Players" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."Players_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 240 (class 1259 OID 30212) +-- Name: ReplayParticipants; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."ReplayParticipants" ( + "Id" integer NOT NULL, + "PlayerGuid" uuid NOT NULL, + "ReplayId" integer NOT NULL, + "Username" text DEFAULT ''::text NOT NULL +); + + +ALTER TABLE public."ReplayParticipants" OWNER TO postgres; + +-- +-- TOC entry 239 (class 1259 OID 30211) +-- Name: ReplayParticipants_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."ReplayParticipants" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."ReplayParticipants_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 217 (class 1259 OID 30050) +-- Name: Replays; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."Replays" ( + "Id" integer NOT NULL, + "Map" text, + "Gamemode" text NOT NULL, + "RoundEndText" text, + "ServerId" text NOT NULL, + "EndTick" integer NOT NULL, + "Duration" text NOT NULL, + "FileCount" integer NOT NULL, + "Size" integer NOT NULL, + "UncompressedSize" integer NOT NULL, + "EndTime" text NOT NULL, + "Link" text DEFAULT ''::text NOT NULL, + "Date" timestamp with time zone, + "RoundId" integer, + "ServerName" text, + "RoundEndTextSearchVector" tsvector GENERATED ALWAYS AS (to_tsvector('english'::regconfig, COALESCE("RoundEndText", ''::text))) STORED NOT NULL, + "Maps" text[] +); + + +ALTER TABLE public."Replays" OWNER TO postgres; + +-- +-- TOC entry 216 (class 1259 OID 30049) +-- Name: Replays_Id_seq; Type: SEQUENCE; Schema: public; Owner: postgres +-- + +ALTER TABLE public."Replays" ALTER COLUMN "Id" ADD GENERATED BY DEFAULT AS IDENTITY ( + SEQUENCE NAME public."Replays_Id_seq" + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1 +); + + +-- +-- TOC entry 215 (class 1259 OID 30044) +-- Name: __EFMigrationsHistory; Type: TABLE; Schema: public; Owner: postgres +-- + +CREATE TABLE public."__EFMigrationsHistory" ( + "MigrationId" character varying(150) NOT NULL, + "ProductVersion" character varying(32) NOT NULL +); + + +ALTER TABLE public."__EFMigrationsHistory" OWNER TO postgres; + +-- +-- TOC entry 4969 (class 0 OID 30099) +-- Dependencies: 222 +-- Data for Name: AccountSettings; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."AccountSettings" ("Id", "RedactInformation", "Friends") FROM stdin; +1 f {} +2 f {} +3 t {} +\. + + +-- +-- TOC entry 4971 (class 0 OID 30107) +-- Dependencies: 224 +-- Data for Name: Accounts; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."Accounts" ("Id", "Guid", "Username", "IsAdmin", "SettingsId", "FavoriteReplays", "SavedProfiles", "Protected") FROM stdin; +1 00000000-0000-0000-0000-000000000000 [System] Unauthenticated user f 1 {} {} f +2 0f80cf86-fdc6-4fc1-a075-4d872578b3cc Simyon t 2 {} {} f +3 8ced134c-8731-4087-bed3-107d59af1a11 Crusaderr f 3 {} {} t +\. + + +-- +-- TOC entry 4981 (class 0 OID 30171) +-- Dependencies: 234 +-- Data for Name: CharacterData; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."CharacterData" ("Id", "CollectedPlayerDataPlayerGuid", "CharacterName", "LastPlayed", "RoundsPlayed") FROM stdin; +\. + + +-- +-- TOC entry 4974 (class 0 OID 30138) +-- Dependencies: 227 +-- Data for Name: GdprRequests; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."GdprRequests" ("Guid") FROM stdin; +\. + + +-- +-- TOC entry 4973 (class 0 OID 30120) +-- Dependencies: 226 +-- Data for Name: HistoryEntry; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."HistoryEntry" ("Id", "Action", "Time", "Details", "AccountId") FROM stdin; +1 Login 2024-08-26 03:12:26.865234+02 \N 2 +2 MainPageViewed 2024-08-26 03:12:27.059246+02 2 +3 MainPageViewed 2024-08-26 03:13:02.740488+02 2 +4 MainPageViewed 2024-08-26 03:17:56.421844+02 2 +5 LeaderboardViewed 2024-08-26 03:18:04.715924+02 Range: AllTime, Username: , Servers: hullrot, greystation, ebengrad, goobstation, harmony, alamo, rouny_2, rain_one_one_gateway, rain_one_three_core, rain_two_one_tide, Sector Umbra, axolotl, leviathan, lizard, miros, salamander, vulture, Server 1, Server 2, Server 3 2 +6 MainPageViewed 2024-08-26 03:18:15.489048+02 2 +7 ProfileViewed 2024-08-26 03:21:06.070577+02 Player GUID: 8ced134c-8731-4087-bed3-107d59af1a11 Username: Crusaderr 2 +8 ProfileViewed 2024-08-26 03:23:35.046089+02 Player GUID: 8ced134c-8731-4087-bed3-107d59af1a11 Username: Crusaderr 2 +\. + + +-- +-- TOC entry 4983 (class 0 OID 30184) +-- Dependencies: 236 +-- Data for Name: JobCountData; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."JobCountData" ("Id", "CollectedPlayerDataPlayerGuid", "JobPrototype", "RoundsPlayed", "LastPlayed") FROM stdin; +\. + + +-- +-- TOC entry 4985 (class 0 OID 30202) +-- Dependencies: 238 +-- Data for Name: JobDepartments; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."JobDepartments" ("Id", "Job", "Department") FROM stdin; +1 Captain Command +2 HeadOfPersonnel Command +3 ChiefMedicalOfficer Command +4 ResearchDirector Command +5 HeadOfSecurity Command +6 ChiefEngineer Command +7 Quartermaster Command +8 Borg Science +9 Scientist Science +10 ResearchAssistant Science +11 Warden Security +12 Detective Security +13 SecurityOfficer Security +14 SecurityCadet Security +15 MedicalDoctor Medical +16 Chemist Medical +17 Paramedic Medical +18 Psychologist Medical +19 MedicalIntern Medical +20 StationEngineer Engineering +21 AtmosphericTechnician Engineering +22 TechnicalAssistant Engineering +23 Janitor Service +24 Chef Service +25 Botanist Service +26 Bartender Service +27 Chaplain Service +28 Lawyer Service +29 Musician Service +30 Reporter Service +31 Zookeeper Service +32 Librarian Service +33 ServiceWorker Service +34 Clown Service +35 Mime Service +36 CargoTechnician Cargo +37 SalvageSpecialist Cargo +38 Passenger The tide +\. + + +-- +-- TOC entry 4976 (class 0 OID 30144) +-- Dependencies: 229 +-- Data for Name: Notices; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."Notices" ("Id", "Title", "Message", "StartDate", "EndDate") FROM stdin; +1 Test notice Testing. Hello! 2024-06-04 00:00:00+02 2030-12-26 00:00:00+01 +\. + + +-- +-- TOC entry 4967 (class 0 OID 30071) +-- Dependencies: 220 +-- Data for Name: ParsedReplays; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."ParsedReplays" ("Name") FROM stdin; +https://moon.spacestation14.com/replays/leviathan/2024/08/25/leviathan-2024_08_25-09_37-round_63714.zip +https://moon.spacestation14.com/replays/lizard/2024/08/25/lizard-2024_08_25-18_51-round_63749.zip +https://moon.spacestation14.com/replays/miros/2024/08/25/miros-2024_08_25-19_08-round_63751.zip +https://moon.spacestation14.com/replays/salamander/2024/08/25/salamander-2024_08_25-12_24-round_63724.zip +https://moon.spacestation14.com/replays/vulture/2024/08/25/vulture-2024_08_25-12_48-round_63725.zip +\. + + +-- +-- TOC entry 4978 (class 0 OID 30153) +-- Dependencies: 231 +-- Data for Name: PlayerData; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."PlayerData" ("Id", "PlayerGuid", "Username") FROM stdin; +\. + + +-- +-- TOC entry 4979 (class 0 OID 30160) +-- Dependencies: 232 +-- Data for Name: PlayerProfiles; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."PlayerProfiles" ("PlayerGuid", "GeneratedAt", "PlayerDataId", "TotalEstimatedPlaytime", "TotalRoundsPlayed", "TotalAntagRoundsPlayed", "LastSeen", "IsWatched") FROM stdin; +\. + + +-- +-- TOC entry 4966 (class 0 OID 30058) +-- Dependencies: 219 +-- Data for Name: Players; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."Players" ("Id", "AntagPrototypes", "JobPrototypes", "PlayerIcName", "Antag", "ParticipantId", "EffectiveJobId") FROM stdin; +1 {} {HeadOfPersonnel} Dean Corso f 1 2 +2 {} {} alien artifact f 2 \N +3 {} {Passenger} Jane Isemann f 2 38 +4 {} {} Hamlet (124) f 2 \N +5 {} {SalvageSpecialist} Shogun Killa f 3 37 +6 {} {StationEngineer} Xavrire f 4 20 +7 {} {Passenger} Kaleb King f 5 38 +8 {} {Clown} Nori f 6 34 +9 {} {MedicalDoctor} Edwin Northey f 7 15 +10 {} {Scientist} Roy Jackson f 8 9 +11 {} {Detective} Otto Janick f 9 12 +12 {} {Warden} Cooliano Rizzo f 10 11 +13 {} {Passenger} Lori Kaur f 11 38 +14 {} {} Yorick f 11 \N +15 {} {Bartender} Boofs-The-Bingle f 12 26 +16 {} {StationEngineer} Kennard Green f 13 20 +17 {} {Passenger} Chais Freeman f 14 38 +18 {} {Passenger} Adan Quinn f 15 38 +19 {} {Librarian} Dottie Valentine f 16 32 +20 {} {Scientist} Adam Ryals f 17 9 +21 {} {MedicalIntern} Blake Dugmore f 18 19 +22 {} {SecurityCadet} Johnny Clain f 19 14 +23 {} {SecurityCadet} Follows-The-Law f 20 14 +24 {} {SalvageSpecialist} Koho Firefly f 21 37 +25 {Traitor} {Janitor} Bob Rohans t 22 23 +26 {} {Passenger} Jack Pierce f 23 38 +27 {Traitor} {Mime} Luna Deathshead t 24 35 +28 {} {ResearchAssistant} Jerome Jawbone f 25 10 +29 {} {Chemist} Otto Motor f 26 16 +30 {} {} mouse (140) f 27 \N +31 {} {Passenger} Chip Greene f 27 38 +32 {} {TechnicalAssistant} John Doe f 28 22 +33 {} {Chaplain} Emma Faith f 29 27 +34 {Thief} {MedicalDoctor} Hacks-The-Borgs t 30 15 +35 {} {Musician} Christina Ama f 31 29 +36 {Traitor} {Passenger} Sam Artemisia t 32 38 +37 {} {Passenger} Plub Bub f 33 38 +38 {} {Passenger} Josey Tyler f 34 38 +39 {} {Passenger} Suck Eggs f 35 38 +40 {} {Passenger} Alice Liddel f 36 38 +41 {} {Botanist} Jerry Pavlov f 37 25 +42 {} {} hydroponics tray f 38 \N +43 {} {Chef} Lexia Zalack f 38 24 +44 {} {Captain} Giovanni Mariotti f 39 1 +45 {} {} Jonah Beaumont f 40 \N +46 {} {} honkbot (767) f 40 \N +47 {} {} Hingle McCringleberry f 40 \N +48 {} {Passenger} Beela-Beelei f 41 38 +49 {} {ServiceWorker} Johanna Jesse f 42 33 +50 {} {Chef} Rei Northley f 43 24 +51 {} {ChiefMedicalOfficer} Rockeus Honkerthan f 44 3 +52 {} {TechnicalAssistant} Astrikos Astralis f 45 22 +53 {} {Passenger} Liz Watty f 46 38 +54 {} {AtmosphericTechnician} Harold Smalls f 47 21 +55 {} {Passenger} Moon Alfred f 48 38 +56 {} {Borg} Rick Geiger f 49 8 +57 {} {Passenger} Aida Holdeman f 50 38 +58 {} {Borg} Celeste Arkie f 51 8 +59 {} {} Dinky Doodle f 51 \N +60 {} {Passenger} Alex Newbern f 52 38 +61 {} {Botanist} Papivahre f 53 25 +62 {} {HeadOfSecurity} Arthur Duck f 54 5 +63 {} {SecurityOfficer} Shehreyayar f 55 13 +64 {} {Passenger} On-death's-Door f 56 38 +65 {Traitor} {MedicalDoctor} The Cliff of Quietness t 57 15 +66 {} {MedicalIntern} Yinz-Tanaka f 58 19 +67 {} {Passenger} Crevis Gingoid f 59 38 +68 {} {Passenger} Yosef Stuart f 60 38 +69 {} {AtmosphericTechnician} Az f 61 21 +70 {} {} Glorbina Blurble f 62 \N +71 {} {SecurityOfficer} Hides-In-Lockers f 63 13 +72 {} {Passenger} Kytharos f 64 38 +73 {} {Passenger} Percy Madron f 65 38 +74 {} {SecurityOfficer} Hides-in-Disposal f 66 13 +75 {} {Chef} Mack Maxi f 67 24 +76 {} {Quartermaster} Chews-Her-Tail f 68 7 +77 {Thief} {CargoTechnician} Danielle Sparks t 69 36 +78 {} {ServiceWorker} Rubin' McDongin f 70 33 +79 {Thief} {Chemist} Jaseen-Jah t 71 16 +80 {} {SecurityOfficer} Normand Monjeau f 72 13 +81 {} {StationEngineer} Splish f 73 20 +82 {} {Scientist} Woosh-Woosh f 74 9 +83 {} {Passenger} Grubble Skree f 75 38 +84 {} {StationEngineer} Bob Goldmann f 76 20 +85 {} {Passenger} Nick Nice f 77 38 +86 {} {Janitor} Groomoul Brewchin f 78 23 +87 {} {CargoTechnician} Azala-Kur f 79 36 +88 {} {} Sam Roy f 80 \N +89 {} {Scientist} Sebastian Nighteyes f 81 9 +90 {} {Passenger} Bill Mayonaise f 82 38 +91 {} {ResearchDirector} Jayden Lawson f 83 4 +92 {} {} Hugo Dawkins f 84 \N +93 {} {} honkbot (70) f 84 \N +94 {} {SecurityCadet} Nami Orphus f 85 14 +95 {} {} Marrow Stocker f 86 \N +96 {} {} Enrique Eckhardstein f 86 \N +97 {Traitor} {Lawyer} Valeriy Sablin t 87 28 +98 {} {Passenger} Firstleaf of the Oak f 88 38 +99 {} {Passenger} Philip Bratton f 89 38 +100 {} {Passenger} Tobey Crank f 90 38 +101 {} {SecurityCadet} Ripley Longears f 91 14 +102 {} {Bartender} Pimoa Spoderlad f 92 26 +103 {Traitor} {Passenger} Johnny Severus t 93 38 +104 {} {SecurityOfficer} Charlie Patel f 94 13 +105 {} {} Ahaht-Deeja f 95 \N +106 {} {Bartender} Kevin lizz Sword f 95 26 +107 {} {} Joshua Williams f 96 \N +108 {} {Scientist} Calling Cornwall f 97 9 +109 {} {} mouse (106) f 97 \N +110 {} {Janitor} Quinton Zalack f 98 23 +111 {} {Passenger} Blim Blom f 99 38 +112 {} {Lawyer} Heaven Joyce f 100 28 +113 {} {Passenger} Witseidutsei-Weewish f 101 38 +114 {} {} Maxwell Barragy f 102 \N +115 {} {Botanist} Adam Ryals f 103 25 +116 {} {Botanist} Gila-Tanaka f 104 25 +117 {} {Scientist} Dave Curze f 105 9 +118 {} {} Asher Sparkdrawn f 106 \N +119 {} {Librarian} Vavrisrasri f 107 32 +120 {Thief} {SalvageSpecialist} Frank Fletcher t 108 37 +121 {} {Warden} Ricky Mason f 109 11 +122 {} {Captain} Meer-Scale f 110 1 +123 {} {} Emma Faith f 111 \N +124 {} {Passenger} Felix Fulton f 112 38 +125 {} {StationEngineer} Fabe f 113 20 +126 {} {CargoTechnician} Nick Mazapan f 114 36 +127 {} {Scientist} Gorg Bunderson f 115 9 +128 {} {CargoTechnician} Jack Grey f 116 36 +129 {} {} Steve Stevenson f 117 \N +130 {} {} mouse (526) f 117 \N +131 {} {} mouse (603) f 117 \N +132 {} {Paramedic} Sniffs-The-Floors f 118 17 +133 {Traitor} {Passenger} Riff Raff t 119 38 +134 {} {Quartermaster} Pablo Fuchs f 120 7 +135 {Traitor} {Lawyer} Thrug t 121 28 +136 {} {} Cooper Ashbaugh f 122 \N +137 {} {Janitor} Arthur Snyder f 123 23 +138 {} {SecurityOfficer} Hermatiage Vandalias f 124 13 +139 {} {TechnicalAssistant} Rajas Starseeker f 125 22 +140 {} {SalvageSpecialist} Kevin Green f 126 37 +141 {} {Passenger} Suzy-Crath f 127 38 +142 {} {Passenger} Eresus Riversi f 128 38 +143 {} {Chemist} Bethney Bob f 129 16 +144 {} {Passenger} Mothew Cometrider f 130 38 +145 {} {} Anna Skabloof f 131 \N +146 {} {Scientist} Alex Newbern f 132 9 +147 {} {MedicalIntern} Liam Levett f 133 19 +148 {} {} Jim Brown f 134 \N +149 {} {ResearchAssistant} Leeann Leichter f 135 10 +150 {} {Musician} Taz Rocker f 136 29 +151 {} {SecurityOfficer} Bill Drop f 137 13 +152 {} {} plogha f 138 \N +153 {} {AtmosphericTechnician} Hanky M Cranky f 139 21 +154 {} {Chaplain} Dirk Gregory f 140 27 +155 {} {MedicalIntern} Ra-Binyaar f 141 19 +156 {} {StationEngineer} Calvin Teaspoon f 142 20 +157 {} {Detective} Lav-Ender f 143 12 +158 {} {ResearchDirector} Agrius Nighteyes f 144 4 +159 {} {Clown} Does-whats-Fun f 145 34 +160 {Thief} {AtmosphericTechnician} Erisia Eneka t 146 21 +161 {} {ChiefEngineer} Terry Whyte f 147 6 +162 {} {MedicalIntern} Ruby Epiolos f 148 19 +163 {} {MedicalDoctor} Olivia Croft f 149 15 +164 {} {SecurityOfficer} Huleeya-Parash f 150 13 +165 {} {Chef} Dominic Bowchiew f 151 24 +166 {Traitor} {CargoTechnician} Irvine Reid t 152 36 +167 {} {Passenger} Rexataxa f 153 38 +168 {} {Chef} Rubin' McDongin f 154 24 +169 {} {Passenger} Glip Glop f 155 38 +170 {Traitor} {Chemist} Simon Firebrush t 156 16 +171 {Traitor} {Passenger} Kel Boilerplate t 157 38 +172 {Traitor} {Mime} Malachi Parkinson t 158 35 +173 {} {HeadOfPersonnel} Angel Laborde f 159 2 +174 {} {StationEngineer} Jimmy Williams f 160 20 +175 {} {Borg} Alira Blexiera f 161 8 +176 {} {HeadOfSecurity} Jonathon Stone f 162 5 +177 {} {Passenger} Wraxita Winter f 163 38 +178 {} {Passenger} Cherno Sabre f 164 38 +179 {} {StationEngineer} Philip Bratton f 165 20 +180 {} {Reporter} Trogloraptor Personatus f 166 30 +181 {} {} Jeff Sadler f 167 \N +182 {} {Borg} Frank Focell f 168 8 +183 {} {MedicalDoctor} Larry Parker f 169 15 +184 {Thief} {Scientist} Walks-The-Walk t 170 9 +185 {} {SalvageSpecialist} Thomas Gray f 171 37 +186 {} {ChiefEngineer} Brian Darmidge f 172 6 +187 {Zombie} {ChiefMedicalOfficer} Ben Rettermann t 173 3 +188 {} {Paramedic} Kaiser Scorchedwing f 174 17 +189 {} {} Aurora Blackwitch f 175 \N +190 {} {HeadOfPersonnel} Jayson Marshall f 176 2 +191 {} {SecurityCadet} Caesar Stargazer f 177 14 +192 {Zombie} {Psychologist} Marcus Keener t 178 18 +193 {} {CargoTechnician} Burt Boulders f 179 36 +194 {TraitorSleeper} {SalvageSpecialist} Kellan Fraser t 180 37 +195 {} {} zombified yellow slime (676) f 180 \N +196 {TraitorSleeper} {SalvageSpecialist} Koho Firefly t 181 37 +197 {Zombie,InitialInfected} {CargoTechnician} Zack Williams t 182 36 +198 {Zombie,Dragon} {} space dragon (153) t 182 \N +199 {} {} Gigglesworth f 182 \N +200 {} {} Emma Faith f 183 \N +201 {} {} Erebus Flamecoat f 184 \N +202 {} {Captain} Losi Fier f 185 1 +203 {Zombie} {Chemist} William Moretti t 186 16 +204 {} {SecurityCadet} Sylvester Woodward f 187 14 +205 {} {} Bodie Larocque f 188 \N +206 {} {} Luanne Neely f 189 \N +207 {} {HeadOfSecurity} Garry Gaudy f 190 5 +208 {Zombie} {MedicalDoctor} Has-Seen-Everything t 191 15 +209 {} {StationEngineer} Rocko Baws f 192 20 +210 {} {Scientist} The Glory of Morning f 193 9 +211 {Zombie} {Chef} Bella Donna t 194 24 +212 {} {} Tar-Shaleez f 194 \N +213 {} {} zombified lizard (218) f 195 \N +214 {} {} Bone Burch f 195 \N +215 {Zombie,InitialInfected} {AtmosphericTechnician} Oscar Stephenson t 195 21 +216 {} {} zombified chicken (19) f 195 \N +217 {Zombie} {} clown spider (686) t 195 \N +218 {} {} zombified Bandito (967) f 195 \N +219 {} {Chaplain} Nicole Harrow f 196 27 +220 {} {} Trash Master (356) f 197 \N +221 {} {} zombified green slime (307) f 197 \N +222 {} {} The soul of silent salt (230) f 197 \N +223 {} {} Timothy Scorchedwing f 197 \N +224 {} {} Burns the Flame f 197 \N +225 {} {SalvageSpecialist} Larry Davidson f 198 37 +226 {} {StationEngineer} Gerald McWilliam f 199 20 +227 {} {Chemist} Hans Freimann f 200 16 +228 {Zombie,InitialInfected} {Botanist} Uland Grower t 201 25 +229 {} {} zombified Morticia (186) f 201 \N +230 {} {Mime} November Juliet f 202 35 +231 {} {AtmosphericTechnician} Zack Vader f 203 21 +232 {} {} clown spider (200) f 203 \N +233 {} {} clown spider (80) f 203 \N +234 {} {ResearchAssistant} Meeh-Meenus f 204 10 +235 {} {Passenger} Cletus Sinister f 205 38 +236 {Nukeops} {} Operative X-Ray t 205 \N +237 {Zombie} {Scientist} Bo Thunderfist t 206 9 +238 {} {} zombified Alexander (33) f 206 \N +239 {} {} zombified blue slime (738) f 206 \N +240 {} {} space carp (502) f 206 \N +241 {Zombie} {Botanist} Davis Blyant t 207 25 +242 {} {} Checkers f 207 \N +243 {} {} zombified green slime (42) f 208 \N +244 {} {} space carp (224) f 208 \N +245 {Zombie} {} space carp (352) t 208 \N +246 {Zombie} {CargoTechnician} Judas Peters t 208 36 +247 {} {} Pun Pun (MK-778) f 209 \N +248 {} {} Casper Pedersen f 209 \N +249 {Zombie} {StationEngineer} Loses-Their-Wrench t 210 20 +250 {Zombie} {Janitor} Laura Andromeda t 211 23 +251 {} {} mothroach (796) f 211 \N +252 {Zombie} {ResearchDirector} Moblin Star-Eye t 212 4 +253 {} {} clown spider (80) f 212 \N +254 {} {} Armando Howard f 212 \N +255 {} {} Tarsals Hoover f 213 \N +256 {Zombie} {CargoTechnician} Xexevi t 213 36 +257 {} {} mouse (407) f 213 \N +258 {} {} mouse (90) f 213 \N +259 {SpaceNinja} {} Merciless Baki t 214 \N +260 {} {TechnicalAssistant} Joshua Grac f 214 22 +261 {Zombie} {MedicalIntern} Sarah Santana t 215 19 +262 {} {} zombified lizard (483) f 215 \N +263 {} {SecurityCadet} Otis Nguyen f 216 14 +264 {} {} space carp (380) f 217 \N +265 {} {} zombified lizard (483) f 217 \N +266 {} {} space carp (352) f 217 \N +267 {Zombie} {} space carp (10) t 217 \N +268 {} {Bartender} Axel Clay f 217 26 +269 {} {} zombified Morticia (186) f 217 \N +270 {} {} zombified Cletus Sinister f 217 \N +271 {} {} clown spider (466) f 217 \N +272 {} {Passenger} Fires-At-Innocents f 218 38 +273 {Zombie} {Chef} Leth Himkoog t 219 24 +274 {} {Chemist} Harmony Harrison f 220 16 +275 {Traitor} {Clown} Silent Joey t 221 34 +276 {} {ResearchDirector} Marty MacMurdock f 222 4 +277 {} {StationEngineer} Andrew Morris f 223 20 +278 {} {} Angelo Marryman f 224 \N +279 {} {Borg} Marc Fuchs f 225 8 +280 {} {Detective} Dandruff Cream f 226 12 +281 {} {Mime} Firefly Nightwish f 227 35 +282 {} {CargoTechnician} Pechaka f 228 36 +283 {} {} Max Wax f 229 \N +284 {} {SecurityOfficer} Diamond Fea f 230 13 +285 {} {Chef} Greenus Man f 231 24 +286 {} {} Kellanna Allaris f 232 \N +287 {} {} Clavicle Mull f 232 \N +288 {} {AtmosphericTechnician} Emerson Hill f 233 21 +289 {} {StationEngineer} Flips-the Flap f 234 20 +290 {} {Passenger} Val Morozova f 235 38 +291 {} {SecurityOfficer} Tan-Kuz f 236 13 +292 {} {SalvageSpecialist} Arcticia Iceborne f 237 37 +293 {} {HeadOfSecurity} Mercer Bray f 238 5 +294 {} {AtmosphericTechnician} Moff Infernus f 239 21 +295 {} {MedicalDoctor} James Rondo f 240 15 +296 {} {Scientist} Randy Farandy f 241 9 +297 {} {} Cuprum Splendens f 242 \N +298 {SpaceNinja} {} Striker Hiryu t 242 \N +299 {Traitor} {CargoTechnician} Ruby Blackthorn t 243 36 +300 {} {SecurityOfficer} Joseph Ward f 244 13 +301 {} {Janitor} Natalie Evans f 245 23 +302 {} {ChiefMedicalOfficer} Joshua Treeby f 246 3 +303 {} {} Arthur Kuster f 247 \N +304 {} {} mouse (738) f 247 \N +305 {} {} ravager (477) f 247 \N +306 {} {} space carp (92) f 247 \N +307 {} {} Pun Pun (MK-826) f 248 \N +308 {} {} Yevu Ressid f 248 \N +309 {} {Paramedic} Richard Tann f 249 17 +310 {} {} Jessica Evileenie f 250 \N +311 {} {} ravager (477) f 250 \N +312 {} {} Pip Soak f 251 \N +313 {Dragon} {} space dragon (686) t 251 \N +314 {} {Passenger} Finnd-Ithar f 252 38 +315 {} {Warden} Zam Asee f 253 11 +316 {} {} Charlie Patel f 254 \N +317 {} {} Austin Nicholas f 255 \N +318 {} {} Ironnal-Wariona f 256 \N +319 {} {} Marrow Zalack f 256 \N +320 {} {} Nina Prechtl f 257 \N +321 {} {} Ulna Kirkson f 257 \N +322 {} {Chef} Bar-Talen f 258 24 +323 {} {Passenger} Eats-The-Uranium f 259 38 +324 {} {CargoTechnician} Isaac Katz f 260 36 +325 {} {Chemist} Joe Ded f 261 16 +326 {} {Janitor} Joe Tanner f 262 23 +327 {} {Captain} Blod Seleda f 263 1 +328 {} {} Honker f 263 \N +329 {} {} Ziggy Orion f 264 \N +330 {} {} mothroach (695) f 264 \N +331 {} {} mothroach (157) f 264 \N +332 {} {} mouse (104) f 264 \N +333 {} {SecurityOfficer} Seeks-The-Truth f 265 13 +334 {} {HeadOfSecurity} Theta Sigma f 266 5 +335 {} {} Goose McSunny f 266 \N +336 {} {} Aranea Adastra f 267 \N +337 {} {} Melvin Mops f 268 \N +\. + + +-- +-- TOC entry 4987 (class 0 OID 30212) +-- Dependencies: 240 +-- Data for Name: ReplayParticipants; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."ReplayParticipants" ("Id", "PlayerGuid", "ReplayId", "Username") FROM stdin; +1 350ad42f-16ed-463d-88d9-c838f41575f1 1 777TRC777 +2 17215685-497d-4269-962a-7f3ea816c673 1 AboveDeceased +3 cd5b1537-4d17-4e34-97e5-9d2d0dc56e0b 1 Ackrilix +4 1205fcc1-0ca6-4f48-a2e3-cf163629eaba 1 Akurra +5 496667f7-8227-4132-90fa-62787a4ebaa7 1 AlexanceT +6 bb3ab7e9-4c23-48e0-bf7c-454ad8f888c1 1 AlexbossulXXL +7 5b358357-caca-4eda-b323-50af0ab072bf 1 Alternis478 +8 e57f9dc1-af1e-42b3-8d05-2997f9916be4 1 BigSwagMcgeeCowLover +9 78f489ce-8c41-4e07-87ac-646b931c2dc7 1 BigV +10 2ea6f669-9cad-4dc5-bf49-f29551b58444 1 BloodySkull54 +11 f96b1a09-0976-4d4d-9949-ca4091dfa3e3 1 Bobylein +12 de07a21a-b3d6-403d-bccd-2bedaa2810d7 1 BoofsBingle +13 9cb3ae16-47f4-469f-b423-c1759eb74f5d 1 busco +14 c811e39c-fd72-4f2b-bf06-ca3bf563e1fb 1 Chaisftw +15 d5e849a2-4dea-4c2f-8871-574820071ed1 1 choucroute +16 1233e6a0-45aa-447f-88d3-257676e4b9f9 1 Claowdy +17 300c1192-6855-4356-b568-dd234de61082 1 Crotalus +18 bc7cf585-a3a2-4e83-917c-16e3ac755249 1 CubeLooch +19 d34f778a-16d1-4fc9-9167-6bebdd9ea66f 1 D0ndee +20 75ef3bc8-596b-4393-9a6c-c3a8a41cc332 1 DapperApple +21 35e8113b-e644-4933-8b34-b0e639b6be4a 1 DarkObserver +22 f2b6d9c6-de50-4cc7-9c33-cda9e4c44a3c 1 deathmaster +23 4beb8dc1-b746-4961-8615-56a044dfe5ac 1 dekigangsta +24 3b34ba5f-e2a7-44e6-bbe6-5bf0618a79e3 1 DORB +25 2896ba2b-7a80-4d83-9f2c-a0bdbd0823be 1 Dourbii +26 a6fe8d86-f8e3-4eab-ab25-a8b01e7c18a2 1 DownwardSpiral +27 9d6052fb-6051-4af7-a298-cdac4322e29e 1 Droo +28 59560c01-ce37-475a-a9f6-56337a47fd4e 1 dudonedid +29 aac26166-139a-4163-8aa9-ad2a059a427d 1 EmmaFaith +30 fb12f6c4-4a3a-41b6-85a8-33224267b0d7 1 Erstucaulk +31 78a76ae8-8d8d-4210-a724-a9d497c7ddbf 1 Evige +32 4866bfc6-5a76-418b-85c7-d2d9d78821f6 1 fatfsaam2 +33 af57604e-a220-43cc-9051-46e5657aee1f 1 FluffyChsBurger +34 f04adc7e-a5a5-49a7-8f86-2301cd042bb5 1 GE_Turok +35 c24f5d86-0de7-4d30-8dd2-d2fefa814abb 1 Geniebattler +36 8338a623-556e-435f-bbbf-c741d00ef174 1 Godvalve +37 b4677cda-6222-4b1f-94ad-09e54d535d96 1 Goober3 +38 045b84db-6c2b-4888-8925-f95c8eeccf1c 1 Habagnawagne +39 ac26c39f-2a63-418f-b02d-221570f789be 1 JohnDoom +40 ccb39944-c2ed-4af0-8649-1b69112c2749 1 Jone +41 2d813621-d222-4a79-b131-fa46460583a5 1 junkgle +42 ffbbe009-ea8f-4a61-ada6-1612fd165bd2 1 Kashatriya +43 065afffd-b40a-4b86-b077-e6e0d5d75fc2 1 kirakira +44 171dc007-c71d-48cc-9bf5-b7e05242954f 1 Krispy_Lime +45 0841051e-c2c5-43fc-bde2-d3a5f491120c 1 KumanekoSeishin +46 0bd50b6e-171b-460e-9d9a-6ff5415f9f4a 1 LizbethW +47 666d9546-dfe9-4644-a9b3-a3a163046925 1 lumpylemons +48 2eca67d6-4963-46da-ba3f-add44bff5139 1 meca_moon +49 ae8db673-824c-4a67-b659-6ca2b70c1cb2 1 Mehik +50 26ad6e5d-992a-4d24-b60c-f3f35e7c939e 1 MidoriKurage +51 045f5df3-6590-4143-b01d-c6586dd32d22 1 Minute_by_Minute +52 ed2469cb-1c58-49ae-8c0f-c5205627182c 1 Naroc +53 b5604719-59b1-4276-9cc5-18b9461f178b 1 omgkonrad +54 6b1432d0-a6e1-45bc-af59-1300bbaaa8d1 1 pirat13 +55 d1fc4042-869c-4911-9111-84f3ede57d32 1 plogha +56 a14cd520-228e-405f-a512-ed9ea7ff1cc5 1 pory50 +57 f9d11bcc-5045-48d5-b503-c36bc2ee0913 1 PPicapiedra +58 a9f7c0ab-3324-45a5-8128-35d778fcfc9c 1 ProGamer777 +59 fd0b9cf1-68e1-4d97-8d39-7e2097d54abb 1 qwerltaz +60 d04b5480-fbad-4cce-8c8e-f4f1ac8048de 1 realnub +61 38728575-45ac-4fc1-8060-1023e2b7db6a 1 REEDRIFF +62 25bb77de-55f9-4db5-8606-1680ad688319 1 Rekides +63 f52880ab-e06a-4702-84bc-07b2f1e47af4 1 Rellu +64 bae780a0-8dd1-4ba0-a5cd-74a288a66446 1 Saiiryn +65 d6d1ee22-2984-4a63-9619-91bf7d457a09 1 Salpish +66 8dcc5465-0153-44b3-a00c-80514070969c 1 Selfie +67 38628586-aaf9-4a92-a42c-1f26903c19e4 1 Shamebase +68 9041ecc2-20cf-4fa4-8226-ea44fb09b209 1 ShiggyLiz +69 63bbbc13-e926-4854-8bd5-dc9c94178282 1 Shromply +70 a7541335-40db-4c62-852a-25053dc48f2e 1 SladeAZ +71 ae6fceec-8066-4083-96db-5d8977054893 1 SledgeD +72 4f4e819e-414e-484f-a69c-234245fa97c5 1 soup123 +73 7c17d6e7-077c-450a-a434-f9f11fd7c340 1 Starcade +74 3ee56186-8c31-48f4-9ea0-99eaf9d303e8 1 supergoldendor +75 947f20e1-156e-484d-9e9b-8c965f7363cd 1 SwordWoof +76 b8f06154-b2d9-4133-bc92-22d3684d1b28 1 sypher +77 76a0ad88-1e74-48af-95b1-bda590e982b4 1 theflam +78 94ff212d-0984-4210-b089-fa524aa642bd 1 TheFuRyuSs +79 2ca5806c-1ebf-4ee8-b267-d85c17bdd47d 1 thegaemer +80 14f4f81c-14dd-4b0c-9498-c3d8365646e7 1 TheGlorifiedWard +81 ad388263-808e-4b9c-8cbd-ec6671718e46 1 TheGypsyBard +82 d7b24908-ccc6-4aaf-a9f0-b2c0d09eaca4 1 thehomelesshobobutreallystupid +83 26292bad-d97e-4ca2-87b9-26529e28150b 1 thejayslayer99 +84 f16983b7-b0f0-43dd-a915-de668e265a6d 1 tomb_raided +85 2861eb72-930e-48cf-9323-3270f99aa5c4 1 Triynh +86 332cb194-9989-4488-b1be-a243faf3e0ad 1 tunabomber500 +87 da0752a6-4f83-4f99-a06e-47eda06b4366 1 Uga_Buga1906 +88 ae990296-2d83-4f0a-a910-e2b8539fc4ce 1 UpAndLeaves +89 ff73afd6-5e3b-4afc-b865-7c0dfcc005ee 1 UselessMoron +90 5dcff5c4-cfb8-4367-a2c5-d84b5e24f49b 2 17GnomesInATrenchcoat +91 e846588a-1094-450d-a801-8048c3ada323 2 AgentSmithRadio +92 4af0055c-86dc-4ff5-b705-fae33f2a88fa 2 Angry_Thing +93 e71d4e5c-01c5-4cfb-ab88-089ced05d5d1 2 Bandoleiro +94 4bcf2765-bef3-4db5-82b6-2c3258eacd57 2 Baptr0b0t +95 5c7549ba-b701-4adb-8ce1-9c5e2aba8337 2 BeanBois +96 e3c541f8-19b8-4526-b034-88b194ed329c 2 bigman0923 +97 7dc42489-c9c6-418d-b634-dd309920789f 2 Callington +98 3fa3eb44-c32c-46ec-a569-9f86029f4d0c 2 Callmore +99 27373627-6142-4dd0-bf04-bc5f47eef262 2 car_lander +100 35605e65-5634-4158-aa2c-57adad1603a0 2 casca +101 5a0bee28-ff78-4a50-8fdd-9b06f7fdf263 2 CCmeow +102 49dd17b7-1846-4076-8366-fa518557c785 2 clinux +103 300c1192-6855-4356-b568-dd234de61082 2 Crotalus +104 07898ccb-43ca-4736-9cf5-0ffa6a38ca24 2 darksails +105 bcbb9340-37df-4805-a106-6b83a9b040c8 2 dave_curze +106 f2346fcf-6d6e-4db9-b4b2-b7227bf0161f 2 dogelife9000 +107 8fa9fefa-c9b5-4219-8b43-c6439fcbe1a9 2 Dt_Prismo +108 b28a82f2-8502-48d2-997e-b9214b3d0d23 2 EarlGrey +109 30d07bc3-c579-4109-b99d-80f7827947c3 2 Elsai +110 61e5d29d-899d-48eb-9e5e-d71412260568 2 Emilio +111 aac26166-139a-4163-8aa9-ad2a059a427d 2 EmmaFaith +112 d6ab20a9-911b-4f73-8fa2-82b71051c6eb 2 evilbanana +113 bb815335-1e9f-4348-ba83-238ac0fcf444 2 FabenatorDaFluff +114 498c937f-6db0-46b1-92a5-a611067a5128 2 GetOutMarutak +115 6ff07894-3218-4359-943d-517151058a6e 2 GreenArg +116 e51bb23b-ed97-4caa-83c5-3457549c5ce7 2 Happy_Feet +117 e0a58ad1-88c4-4bab-977a-78cad6dfceef 2 HarrierCZ +118 179e9099-3d98-4182-b18d-c867d1000ad8 2 iisazel +119 5293cf44-1e90-4051-b04a-3c6e636ca4aa 2 Jersyjewbear +120 96305545-5b6f-420b-9ab6-6b274b7f691b 2 Jolas +121 212c1771-17ed-444e-90e0-47f791044fef 2 Jumo +122 dcfd23eb-e3c6-40f6-a2c6-440648519882 2 kaomedes +123 cf086a01-9d5d-4a17-89b2-5895be2780ed 2 Katzenminer +124 995efbf7-cab9-4852-a902-c09405eada54 2 Kraaz +125 0ed37583-1ae4-4106-8d51-c8518d9be682 2 LunaticNikra +126 d365c1c4-be74-41b8-986a-022d9f7d44b0 2 MarclundieClumsie +127 131af6fd-4e3d-44b6-b22e-d75dd777fb48 2 meem1246 +128 a6fabd32-7fa7-4f79-960c-d71fabfd4762 2 miaer +129 4f37e118-ec3c-44e7-9a9f-0cb9f1568236 2 Mikroman +130 f641a191-0478-46e6-a064-e0930b9a3ec9 2 MilkiestMan +131 a1537edb-068a-48e8-99e2-c142d07e1a47 2 miscevie_dylo +132 ed2469cb-1c58-49ae-8c0f-c5205627182c 2 Naroc +133 a33316c6-2bcb-4e90-8caf-1e1edeeb3810 2 Opptrocity +134 6e744bcf-fb33-42d1-96a4-e9e5e7535904 2 Overchris55 +135 4fa4b134-025a-4f95-80e1-1edd6035404e 2 PatateAuFour +136 d96c136f-87c2-4771-8960-873719471185 2 Phire +137 14ec9a9d-8a74-428b-9759-a37e6191ecc8 2 pinkshiny +138 d1fc4042-869c-4911-9111-84f3ede57d32 2 plogha +139 25ab89f4-a9a7-44c7-8538-c94e8a086e92 2 Professor_Hanky_Spanky +140 c748f61d-4be5-4bbb-8f58-5d3682bbc6a6 2 Quarternote +141 87e6e7e4-e5b6-4462-b6db-dce54cdb63cd 2 raynorz +142 9f4fbfef-7c17-4e10-8c74-768b215a8ed9 2 real_drteaspoon +143 21a1ac47-9328-4099-9749-9b50af47eaa0 2 Redcat229 +144 6e83f968-bcf5-48bf-a603-b64ad99b95c8 2 RidiculonSkull +145 bd54a379-8cd0-4b17-8e93-91bded0c5eb4 2 robin_is_best +146 ce3ed35e-c98e-431f-9698-144ab654ccde 2 rotty +147 07ce421c-00de-4eb3-a3d2-672961b26c23 2 RowntreeMackay +148 54984b2e-ef4e-4696-92f7-d71235e46813 2 sabugo +149 152e4731-ae21-45b0-a941-0cf99beb4308 2 salthew +150 db95018b-82a4-4448-9051-3dcfa739ba0b 2 Scheritt +151 c43cfe17-0f30-4df6-88ac-3c2fb1b930a9 2 SconeCptRex +152 7075a5a7-5824-4ec3-b155-c5472001809f 2 SkrubQuill +153 8d70e93a-4c28-4ee2-86de-f7fcf4e3d394 2 Skulker +154 a7541335-40db-4c62-852a-25053dc48f2e 2 SladeAZ +155 7b4712c1-523b-4315-b12a-a6732203751c 2 slugmaster1 +156 656315bd-ddf8-460f-a2c1-3d990a41e47d 2 staffassistantidfabri +157 2e556efc-c37c-4c4a-a28b-3fd05fe751ed 2 swix1200 +158 78dcccfd-51c8-4642-a70f-05e0e3e68f37 2 Sylvestertalone +159 84698f2b-cf31-411e-8e37-124ec97d8a8e 2 ThaiNoodles +160 3902abd6-aaf7-452c-af04-ceca570903c9 2 TheButteryJoke +161 64e32201-5371-4485-a77a-c92993227248 2 thelostone +162 179d5e03-6b1a-4f92-bb31-2f4fe4fd631d 2 ToasterStrudels +163 3806594f-23d2-4743-ae17-1c16a5abde21 2 Torern +164 04e4256a-f52a-4330-8e26-4751eea91f6c 2 Unc_jawny +165 ff73afd6-5e3b-4afc-b865-7c0dfcc005ee 2 UselessMoron +166 b2bd530e-91ad-411c-95d4-c6df0e5ecdfa 2 Viim +167 9ecce829-3b4f-4bc5-bf64-126076e856db 2 voidnull +168 8384ae0f-9ade-4219-8516-27784cd5dc13 2 VonJaeger +169 b3aa7a37-8a6f-469e-9d34-b5967ff18ebd 2 Weeperr +170 fc52115a-2ed4-41eb-a628-f85cc57a730a 2 Westferb +171 1ec7c123-d650-44eb-93c9-f0b4f3f23481 2 ZeeThree +172 2cc4e666-4b8c-470a-9d92-032e0ddbf7ec 3 3LetterFederalAgent +173 c85aa3df-3ea6-4779-ad88-69631c401b5f 3 AMinnesotan2 +174 8fd7a19e-d60b-47e1-b705-3c68572b1a55 3 AppleC +175 1449c1ec-4629-4df0-837a-43e081bac5b6 3 AprilMoxt +176 40f7de89-0618-454b-ba6d-6e7b1060b66a 3 ArekAS +177 93ebd3ce-7afb-4733-89fb-a95a673050db 3 Bigpooper +178 f2133418-19d1-4419-8523-7178b17def15 3 Bobberson +179 f4a82ba8-c91c-4165-878b-b8b1b9e888d0 3 bumholymoly +180 8ced134c-8731-4087-bed3-107d59af1a11 3 Crusaderr +181 35e8113b-e644-4933-8b34-b0e639b6be4a 3 DarkObserver +182 e03bae9a-aa55-4f4b-a44f-878c4d175ce5 3 dogjeff07 +183 aac26166-139a-4163-8aa9-ad2a059a427d 3 EmmaFaith +184 a70b95d2-a443-4d0b-8cae-4f2129abdbf5 3 Eternal86 +185 5d8302af-d36a-4523-8165-bb175c0049f1 3 FieryONE_LOST +186 793422e7-e3e7-4335-a72b-3b0d2eb78d05 3 Flamebrain +187 ae56fbcf-6c02-4c5d-9bfa-a2ee6e26ce8e 3 FunStickman +188 9928ea20-effc-461d-914b-396f40167ed6 3 geekyhobo +189 f2724d66-2bbd-45fe-b7a5-b209836b5062 3 GelEss +190 74d4919c-498e-4030-9392-84362ae0eb51 3 GreatestUsername +191 1e98cf4f-2d09-40c9-bf2e-182fa90ffccc 3 Harryrod +192 5caef62e-6041-4c23-8a2e-64ba27056e75 3 Hreno +193 dd37f96f-205c-406d-a370-8719823b95d6 3 Ilmfun +194 5d45ce22-db8d-4856-b0ff-0431100ffaeb 3 imjustagoblin +195 42c7d078-7ece-4898-b36e-fd64a5cbc614 3 JuanThang +196 9fd7116e-a55f-4807-84e4-18f417b1a994 3 Kogan +197 92a986f6-cff0-44b5-89aa-5b7a237fbe62 3 LittleLink +198 29138005-8009-49b5-8b0a-d53876eb1c3e 3 LordZirconium +199 f558a2b3-94b8-4e9c-82e5-4b75f3ee0865 3 Matrex +200 db4dbcf1-90fa-422f-a1f8-c27c176eb6da 3 Matthrew +201 135e6d62-1f9b-487c-9bae-86e158e13f20 3 Nevim +202 d953132b-848f-4195-a620-9676b6a2bce9 3 NovemberJuliete +203 b5604719-59b1-4276-9cc5-18b9461f178b 3 omgkonrad +204 d97a7f83-f707-40f2-80c1-5bfaa9b51586 3 peat +205 34036e3e-5d71-4d80-825b-0590dcde3cb0 3 ProfessionalDumbass +206 142f1ecd-1f49-462d-88fd-1385ce499be3 3 PunchAttack +207 a904a719-0dee-445e-b906-2d2905b6e707 3 RatherUncreativeName +208 733ec608-3263-443f-bd90-49c1a8ce786d 3 ShroomMaYo +209 9123fac4-0eeb-4ff4-b883-4a0382000daa 3 SilverCan +210 f0b13c6f-5ccb-4d9e-80a5-3037cd19dee7 3 Skye704 +211 230aca02-7313-4b1b-b374-582a299fcb89 3 SomeKittyCat +212 51023a6d-6988-4646-8aba-8de424910d33 3 spacebat +213 0c38e08d-9ba3-446b-b72a-d6f8ec127942 3 spinzir +214 9603f8c1-f33e-4fae-a68c-96acd642fe63 3 TakuTaco +215 d42b6cbc-ceb5-4353-8851-345501fc0b35 3 theachevah +216 2b009f60-9632-451c-8219-9a897d225cca 3 Theoran12 +217 b9551ad5-01da-431e-bf69-020f226f4e6d 3 Tyleri55 +218 29f873f7-1474-4e45-9f14-6ec988549477 3 WarCrimingIt +219 61386d61-ebaf-4406-a876-985b6a8324b5 3 ZanexFlex +220 b36c7228-41a5-4bee-a9bf-a8e26788e601 4 aCobOfCorn +221 44939cbd-e1fe-4352-918a-1b5abab68ca0 4 Aegledis +222 3f164beb-908b-4d13-8b2f-1bb3ce3c38bc 4 Arnesio +223 150680db-2ad6-475a-8dc9-b8812825ea39 4 batsujikan +224 95d22b3f-7839-425e-939f-10dd08936d37 4 Cisco +225 d199781b-c109-4f9a-98d1-6b9a738a2379 4 ColdDead +226 0b90c79c-9822-451b-8d4a-8edd0aa5feaa 4 dandruff +227 4ff2e69a-6bc4-48aa-8538-3910fc87e638 4 dragongaming2345 +228 9d6052fb-6051-4af7-a298-cdac4322e29e 4 Droo +229 b2226f49-3049-4f6b-95e8-965bc1e53462 4 FriekandelKaaskroket +230 e6a1b383-4df5-4bc9-b9c3-6b88a3760c88 4 honkingoose +231 0001ec6e-39a5-4eaa-8376-5a62992edc8f 4 karallie +232 cdb792a9-4511-4641-9b9e-e80d58b6b4a1 4 Kellanna +233 269e2a77-db23-495b-acf8-db40eca43c5e 4 Kenkaito +234 f8ebc896-47e6-4d63-9f3c-306b041c2b1f 4 kiwiiiiii +235 5e1dd73e-19ed-4205-a6ee-378a2000fb4a 4 littleNorthStar +236 7888c653-770c-4619-80cb-7e3dcdd091e8 4 M4ShermanBattleTank +237 4b6138a5-7fee-4c7f-bb49-cafe013004c2 4 Maestro2Kimpembe +238 a579b184-0f04-4637-ba03-d02562b919f5 4 Mercer_Bray +239 060eaf83-b447-45ac-aaaa-fe93f6889dce 4 Namik +240 776e8707-adc7-49a9-adcc-d5990ab6d66e 4 ReboundQ3 +241 fe61a8c0-27a8-47f2-8176-29f406f9edf5 4 Ripotoo +242 549040a8-6ff9-4812-ad01-7c5655bf12d5 4 soulless_drake +243 6c314876-bd70-4f96-80b1-3af78553c72e 4 Spaz1705 +244 4e8e5e3a-00e5-46ef-b653-3e46a4d657a6 4 tanuko +245 33aaf760-d6f6-432a-b1d6-c9079024f64e 4 Thatcher_Grey +246 f4d4ea4f-0a73-4936-a9bf-07c1ffdbd860 4 The_Narwhalrus +247 798ade0b-b18a-46e6-9cef-3fb8ac4d6ac5 4 TheAncientKnight +248 4bb0d960-1d0e-40f1-a64f-2ff01a30241a 4 Thefeed +249 585a0e64-3d80-4445-907c-88240e7c72c1 4 TMan66 +250 e595fbc7-7201-406e-92e8-85be250a19f0 4 Tytos +251 a591805d-6447-48eb-8f29-42734c2e9949 4 Xandake +252 f45655e1-6989-4c07-a940-9e151bc88169 4 Xolotl +253 833b2f7e-b7eb-4c25-9c7b-b235ee55ede8 4 Zamasee +254 4bcf2765-bef3-4db5-82b6-2c3258eacd57 5 Baptr0b0t +255 d64778ac-ee71-4cef-afda-a9c757e9e723 5 DoggowithaRocket +256 b2e2aeb3-f07b-4b8f-bc4f-c81b00b2954c 5 Dreaded08 +257 8c6c7157-bc8b-4506-a052-c01de5bc4c8e 5 F1REMEN +258 ed5f2fab-d3fa-42f2-b3b5-f15e9bd721e2 5 JetSetBoomBox +259 1dc668ad-fc69-4c39-96a3-cd6979b15f3e 5 Leviathian_Jager +260 df80529b-7593-4de1-b172-e76b539c274d 5 nszeek +261 e2dddda8-8eb9-46de-8151-c2fca18730c8 5 PashaTechnique +262 6e5e8aa1-31bd-48e2-9a45-2049f87f0507 5 ProntoCheese +263 b8981d80-7868-4013-b2ae-1b85888b8a24 5 Samuel_Wiseman +264 cfb1582a-ece0-4858-b814-330424122f00 5 Smerbert +265 3d9fcf93-3696-419a-8afd-c7b2325aafc6 5 SpaceLizard +266 34746078-61e2-407d-98cd-1e949dacc399 5 TheSilliest_Ever +267 540a12cb-14c7-44d5-adff-9b69a1135846 5 ViceEmargo +268 0a99d615-c769-497c-a8c3-df26b07d74e3 5 VincentTogo +\. + + +-- +-- TOC entry 4964 (class 0 OID 30050) +-- Dependencies: 217 +-- Data for Name: Replays; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."Replays" ("Id", "Map", "Gamemode", "RoundEndText", "ServerId", "EndTick", "Duration", "FileCount", "Size", "UncompressedSize", "EndTime", "Link", "Date", "RoundId", "ServerName", "Maps") FROM stdin; +1 Omega Secret \nThere were 3 thiefs.\n\n[color=White]Danielle Sparks[/color] ([color=gray]Shromply[/color]) was a thief who had the following objectives:\n[color=#746694]Criminal[/color]\n- Steal the chemical dispenser. | [color=red]Failure![/color] (0%)\n- Steal the ID Cards (any). | [color=red]Failure![/color] (14%)\n- Steal the bible. | [color=red]Failure![/color] (0%)\n- Steal the figurines (any). | [color=green]Success![/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n\n[color=White]Jaseen-Jah[/color] ([color=gray]SledgeD[/color]) was a thief who had the following objectives:\n[color=#746694]Criminal[/color]\n- Steal the big alien artifact. | [color=red]Failure![/color] (0%)\n- Steal the salvage shuttle console board. | [color=red]Failure![/color] (0%)\n- Steal the ID Cards (any). | [color=red]Failure![/color] (78%)\n- Steal the figurines (any). | [color=red]Failure![/color] (45%)\n- Steal the beer goggles. | [color=green]Success![/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n\n[color=White]Hacks-The-Borgs[/color] ([color=gray]Erstucaulk[/color]) was a thief who had the following objectives:\n[color=#746694]Criminal[/color]\n- Steal Renault. | [color=green]Success![/color]\n- Steal the bible. | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n\n\n\nThere were 5 traitors.\n0 out of 5 traitors were in custody.\n\nThe codewords were: [color=White]subtract, thaw, old, excite[/color]\n[color=White]Bob Rohans[/color] ([color=gray]deathmaster[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n- Ensure fellow traitor Luna Deathshead, Mime stays alive. | [color=green]Success![/color]\n- Ensure fellow traitor Luna Deathshead, Mime stays alive. | [color=green]Success![/color]\n\n[color=White]Valeriy Sablin[/color] ([color=gray]Uga_Buga1906[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n- Ensure fellow traitor Luna Deathshead, Mime stays alive. | [color=green]Success![/color]\n- Ensure fellow traitor Bob Rohans, Janitor stays alive. | [color=green]Success![/color]\n\n[color=White]The Cliff of Quietness[/color] ([color=gray]PPicapiedra[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n- Steal the Chief Medical Officer's handheld crew monitor. | [color=green]Success![/color]\n\n[color=White]Luna Deathshead[/color] ([color=gray]DORB[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n- Kill Giovanni Mariotti, Captain | [color=red]Failure![/color] (0%)\n\n[color=White]Sam Artemisia[/color] ([color=gray]fatfsaam2[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Kill or maroon Splish, Station Engineer | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n- Kill or maroon Shogun Killa, Salvage specialist | [color=red]Failure![/color] (0%)\n\n\n wizards 535108 01:01:05.1630015 648 157278051 692953270 04:57:16.8821631 https://moon.spacestation14.com/replays/leviathan/2024/08/25/leviathan-2024_08_25-09_37-round_63714.zip 2024-08-25 09:37:00+02 63714 leviathan \N +2 Bagel Station Secret \nThere were 3 thiefs.\n\n[color=White]Walks-The-Walk[/color] ([color=gray]Westferb[/color]) was a thief who had the following objectives:\n[color=#746694]Criminal[/color]\n- Steal CMO's Cat. | [color=green]Success![/color]\n- Steal the gold medal of crewmanship. | [color=red]Failure![/color] (0%)\n- Steal the bible. | [color=green]Success![/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n\n[color=White]Frank Fletcher[/color] ([color=gray]EarlGrey[/color]) was a thief who had the following objectives:\n[color=#746694]Criminal[/color]\n- Steal the cargo shuttle console board. | [color=red]Failure![/color] (0%)\n- Steal the warden's cap. | [color=red]Failure![/color] (0%)\n- Steal the figurines (any). | [color=red]Failure![/color] (0%)\n- Steal the beer goggles. | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n\n[bold][color=red]| IN CUSTODY | [/color][/bold][color=White]Erisia Eneka[/color] ([color=gray]rotty[/color]) was a thief who had the following objectives:\n[color=#746694]Criminal[/color]\n- Steal the RD's potted plant. | [color=red]Failure![/color] (0%)\n- Steal the warden's cap. | [color=red]Failure![/color] (0%)\n- Steal the beer goggles. | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n\n\n\nThere were 7 traitors.\n2 out of 7 traitors were in custody.\n\nThe codewords were: [color=White]grab, jog, jealous, ancient[/color]\n[color=White]Kel Boilerplate[/color] ([color=gray]swix1200[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Die a glorious death | [color=green]Success![/color]\n- Kill or maroon Trogloraptor Personatus, Reporter | [color=green]Success![/color]\n- Kill or maroon Trogloraptor Personatus, Reporter | [color=green]Success![/color]\n\n[color=White]Thrug[/color] ([color=gray]Jumo[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n- Steal the Research Director's hand teleporter. | [color=green]Success![/color]\n\n[color=White]Riff Raff[/color] ([color=gray]Jersyjewbear[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Die a glorious death | [color=green]Success![/color]\n- Kill Ricky Mason, Warden | [color=red]Failure![/color] (0%)\n\n[color=White]Simon Firebrush[/color] ([color=gray]staffassistantidfabri[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Kill or maroon Jimmy Williams, Station Engineer | [color=red]Failure![/color] (0%)\n- Kill or maroon Bill Drop, Security Officer | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n\n[bold][color=red]| IN CUSTODY | [/color][/bold][color=White]Irvine Reid[/color] ([color=gray]SkrubQuill[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Kill or maroon Sniffs-The-Floors, Paramedic | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n- Kill or maroon Dominic Bowchiew, Chef | [color=green]Success![/color]\n\n[bold][color=red]| IN CUSTODY | [/color][/bold][color=White]Malachi Parkinson[/color] ([color=gray]Sylvestertalone[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Steal the captain ID card. | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n\n[color=White]Johnny Severus[/color] ([color=gray]Bandoleiro[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Kill Ricky Mason, Warden | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n\n\n wizards 453690 00:24:50.1985098 413 80459671 460658359 04:12:02.9515437 https://moon.spacestation14.com/replays/lizard/2024/08/25/lizard-2024_08_25-18_51-round_63749.zip 2024-08-25 18:51:00+02 63749 lizard \N +3 Cog Secret \nThere was one ninja.\n\n[color=White]Merciless Baki[/color] ([color=gray]TakuTaco[/color]) was a ninja who had the following objectives:\n[color=#33cc00]Spider Clan[/color]\n- Steal 11 technologies. | [color=green]Success![/color]\n- Doorjack 18 doors on the station. | [color=green]Success![/color]\n- Call in a threat | [color=green]Success![/color]\n- Set everyone to wanted | [color=green]Success![/color]\n- Survive | [color=green]Success![/color]\n\n\n\nThere were 2 traitors.\n0 out of 2 traitors were in custody.\n\nThe codewords were: [color=White]super, wrong, sticky, lie[/color]\n[color=White]Kellan Fraser[/color] ([color=gray]Crusaderr[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n- Steal the head of personnel's corgi's prime-cut corgi meat. | [color=red]Failure![/color] (0%)\n\n[color=White]Koho Firefly[/color] ([color=gray]DarkObserver[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Kill or maroon Sylvester Woodward, Security Cadet | [color=red]Failure![/color] (0%)\n- Steal the Chief Engineer's advanced magboots. | [color=red]Failure![/color] (0%)\n\n\n\nThere was one dragon.\n\n[color=White]space dragon (153)[/color] ([color=gray]dogjeff07[/color]) was a dragon who had the following objectives:\n[color=#7567b6]Space Dragon[/color]\n- Open 3 carp rifts | [color=red]Failure![/color] (0%)\n- Survive | [color=red]Failure![/color] (0%)\n\n\n\n[color=crimson]Syndicate minor victory![/color]\nNo nuclear operatives died.\nThe operatives were:\n- [color=White]Operative X-Ray[/color] ([color=gray]ProfessionalDumbass[/color])\n[color=crimson]52.63% of the crew were turned into zombies.[/color]\nThere were 3 initial infected:\n- [color=plum]Zack Williams[/color] ([color=gray]dogjeff07[/color]) was one of the initial infected.\n- [color=plum]Uland Grower[/color] ([color=gray]Nevim[/color]) was one of the initial infected.\n- [color=plum]Oscar Stephenson[/color] ([color=gray]JuanThang[/color]) was one of the initial infected. wizards 1043671 01:19:02.7285906 853 172801336 915840096 09:39:48.9652110 https://moon.spacestation14.com/replays/miros/2024/08/25/miros-2024_08_25-19_08-round_63751.zip 2024-08-25 19:08:00+02 63751 miros \N +4 Packed Secret \nThere was one dragon.\n\n[color=White]space dragon (686)[/color] ([color=gray]Xandake[/color]) was a dragon who had the following objectives:\n[color=#7567b6]Space Dragon[/color]\n- Open 3 carp rifts | [color=red]Failure![/color] (0%)\n- Survive | [color=red]Failure![/color] (0%)\n\n\n\nThere were 2 traitors.\n1 out of 2 traitors were in custody.\n\nThe codewords were: [color=White]discover, modern, bad, kiss[/color]\n[color=White]Ruby Blackthorn[/color] ([color=gray]Spaz1705[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Steal the Research Director's experimental research hardsuit. | [color=red]Failure![/color] (0%)\n- Escape to centcomm alive and unrestrained. | [color=green]Success![/color]\n\n[bold][color=red]| IN CUSTODY | [/color][/bold][color=White]Silent Joey[/color] ([color=gray]Aegledis[/color]) was a traitor who had the following objectives:\n[color=crimson]The Syndicate[/color]\n- Escape to centcomm alive and unrestrained. | [color=red]Failure![/color] (0%)\n- Kill or maroon Randy Farandy, Scientist | [color=red]Failure![/color] (0%)\n- Kill or maroon Andrew Morris, Station Engineer | [color=red]Failure![/color] (0%)\n\n\n\nThere was one ninja.\n\n[color=White]Striker Hiryu[/color] ([color=gray]soulless_drake[/color]) was a ninja who had the following objectives:\n[color=#33cc00]Spider Clan[/color]\n- Steal 10 technologies. | [color=red]Failure![/color] (90%)\n- Doorjack 17 doors on the station. | [color=green]Success![/color]\n- Call in a threat | [color=green]Success![/color]\n- Set everyone to wanted | [color=green]Success![/color]\n- Survive | [color=green]Success![/color]\n\n\n wizards_salamander 248301 00:50:50.2636164 421 106210035 453327694 02:17:56.6583900 https://moon.spacestation14.com/replays/salamander/2024/08/25/salamander-2024_08_25-12_24-round_63724.zip 2024-08-25 12:24:00+02 63724 salamander \N +5 Reach Secret \n wizards 192000 01:44:09.8937501 324 70287935 346194248 01:46:39.9602667 https://moon.spacestation14.com/replays/vulture/2024/08/25/vulture-2024_08_25-12_48-round_63725.zip 2024-08-25 12:48:00+02 63725 vulture \N +\. + + +-- +-- TOC entry 4962 (class 0 OID 30044) +-- Dependencies: 215 +-- Data for Name: __EFMigrationsHistory; Type: TABLE DATA; Schema: public; Owner: postgres +-- + +COPY public."__EFMigrationsHistory" ("MigrationId", "ProductVersion") FROM stdin; +20240217201506_InitialCreate 8.0.2 +20240218120921_ParsedReplays 8.0.2 +20240218132707_Link 8.0.2 +20240219152928_Date 8.0.2 +20240220114603_RoundId 8.0.2 +20240302110641_ServerName 8.0.2 +20240307092154_Indicies 8.0.2 +20240307105528_ForeignKeysPlayer 8.0.2 +20240402222948_RemoveRoundEndTextIndex 8.0.2 +20240411175015_RoundEndTextFullTextSearch 8.0.2 +20240511171159_Accounts 8.0.2 +20240519003137_MarkAccountGuidUnique 8.0.2 +20240531155017_FavoriteReplays 8.0.2 +20240603182443_GdprRequests 8.0.2 +20240616123113_Notices 8.0.2 +20240617134356_SavedProfiles 8.0.2 +20240706161131_ProfileDbCaching 8.0.2 +20240712104031_RemoveForeignKeysJobCOuntCharData 8.0.2 +20240713111810_MultipleMaps 8.0.2 +20240729142846_ProtectedAccounts 8.0.2 +20240820195835_JobDepartmentMap 8.0.2 +20240820204611_ReplayParticipant 8.0.2 +20240820232455_PlayerTrim 8.0.2 +20240821134427_JobForeignKey 8.0.2 +20240826004046_HistoryEntryForeignKeys 8.0.2 +\. + + +-- +-- TOC entry 4993 (class 0 OID 0) +-- Dependencies: 221 +-- Name: AccountSettings_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."AccountSettings_Id_seq"', 3, true); + + +-- +-- TOC entry 4994 (class 0 OID 0) +-- Dependencies: 223 +-- Name: Accounts_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."Accounts_Id_seq"', 3, true); + + +-- +-- TOC entry 4995 (class 0 OID 0) +-- Dependencies: 233 +-- Name: CharacterData_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."CharacterData_Id_seq"', 1, false); + + +-- +-- TOC entry 4996 (class 0 OID 0) +-- Dependencies: 225 +-- Name: HistoryEntry_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."HistoryEntry_Id_seq"', 8, true); + + +-- +-- TOC entry 4997 (class 0 OID 0) +-- Dependencies: 235 +-- Name: JobCountData_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."JobCountData_Id_seq"', 1, false); + + +-- +-- TOC entry 4998 (class 0 OID 0) +-- Dependencies: 237 +-- Name: JobDepartments_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."JobDepartments_Id_seq"', 38, true); + + +-- +-- TOC entry 4999 (class 0 OID 0) +-- Dependencies: 228 +-- Name: Notices_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."Notices_Id_seq"', 1, true); + + +-- +-- TOC entry 5000 (class 0 OID 0) +-- Dependencies: 230 +-- Name: PlayerData_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."PlayerData_Id_seq"', 1, false); + + +-- +-- TOC entry 5001 (class 0 OID 0) +-- Dependencies: 218 +-- Name: Players_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."Players_Id_seq"', 337, true); + + +-- +-- TOC entry 5002 (class 0 OID 0) +-- Dependencies: 239 +-- Name: ReplayParticipants_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."ReplayParticipants_Id_seq"', 268, true); + + +-- +-- TOC entry 5003 (class 0 OID 0) +-- Dependencies: 216 +-- Name: Replays_Id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres +-- + +SELECT pg_catalog.setval('public."Replays_Id_seq"', 5, true); + + +-- +-- TOC entry 4778 (class 2606 OID 30105) +-- Name: AccountSettings PK_AccountSettings; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."AccountSettings" + ADD CONSTRAINT "PK_AccountSettings" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4783 (class 2606 OID 30113) +-- Name: Accounts PK_Accounts; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Accounts" + ADD CONSTRAINT "PK_Accounts" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4799 (class 2606 OID 30177) +-- Name: CharacterData PK_CharacterData; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."CharacterData" + ADD CONSTRAINT "PK_CharacterData" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4788 (class 2606 OID 30142) +-- Name: GdprRequests PK_GdprRequests; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."GdprRequests" + ADD CONSTRAINT "PK_GdprRequests" PRIMARY KEY ("Guid"); + + +-- +-- TOC entry 4786 (class 2606 OID 30126) +-- Name: HistoryEntry PK_HistoryEntry; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."HistoryEntry" + ADD CONSTRAINT "PK_HistoryEntry" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4802 (class 2606 OID 30190) +-- Name: JobCountData PK_JobCountData; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."JobCountData" + ADD CONSTRAINT "PK_JobCountData" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4805 (class 2606 OID 30208) +-- Name: JobDepartments PK_JobDepartments; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."JobDepartments" + ADD CONSTRAINT "PK_JobDepartments" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4790 (class 2606 OID 30150) +-- Name: Notices PK_Notices; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Notices" + ADD CONSTRAINT "PK_Notices" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4776 (class 2606 OID 30077) +-- Name: ParsedReplays PK_ParsedReplays; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."ParsedReplays" + ADD CONSTRAINT "PK_ParsedReplays" PRIMARY KEY ("Name"); + + +-- +-- TOC entry 4792 (class 2606 OID 30159) +-- Name: PlayerData PK_PlayerData; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."PlayerData" + ADD CONSTRAINT "PK_PlayerData" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4796 (class 2606 OID 30164) +-- Name: PlayerProfiles PK_PlayerProfiles; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."PlayerProfiles" + ADD CONSTRAINT "PK_PlayerProfiles" PRIMARY KEY ("PlayerGuid"); + + +-- +-- TOC entry 4774 (class 2606 OID 30064) +-- Name: Players PK_Players; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Players" + ADD CONSTRAINT "PK_Players" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4810 (class 2606 OID 30216) +-- Name: ReplayParticipants PK_ReplayParticipants; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."ReplayParticipants" + ADD CONSTRAINT "PK_ReplayParticipants" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4769 (class 2606 OID 30056) +-- Name: Replays PK_Replays; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Replays" + ADD CONSTRAINT "PK_Replays" PRIMARY KEY ("Id"); + + +-- +-- TOC entry 4762 (class 2606 OID 30048) +-- Name: __EFMigrationsHistory PK___EFMigrationsHistory; Type: CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."__EFMigrationsHistory" + ADD CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY ("MigrationId"); + + +-- +-- TOC entry 4779 (class 1259 OID 30136) +-- Name: IX_Accounts_Guid; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE UNIQUE INDEX "IX_Accounts_Guid" ON public."Accounts" USING btree ("Guid"); + + +-- +-- TOC entry 4780 (class 1259 OID 30133) +-- Name: IX_Accounts_SettingsId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Accounts_SettingsId" ON public."Accounts" USING btree ("SettingsId"); + + +-- +-- TOC entry 4781 (class 1259 OID 30134) +-- Name: IX_Accounts_Username; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Accounts_Username" ON public."Accounts" USING btree ("Username"); + + +-- +-- TOC entry 4797 (class 1259 OID 30196) +-- Name: IX_CharacterData_CollectedPlayerDataPlayerGuid; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_CharacterData_CollectedPlayerDataPlayerGuid" ON public."CharacterData" USING btree ("CollectedPlayerDataPlayerGuid"); + + +-- +-- TOC entry 4784 (class 1259 OID 30135) +-- Name: IX_HistoryEntry_AccountId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_HistoryEntry_AccountId" ON public."HistoryEntry" USING btree ("AccountId"); + + +-- +-- TOC entry 4800 (class 1259 OID 30197) +-- Name: IX_JobCountData_CollectedPlayerDataPlayerGuid; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_JobCountData_CollectedPlayerDataPlayerGuid" ON public."JobCountData" USING btree ("CollectedPlayerDataPlayerGuid"); + + +-- +-- TOC entry 4803 (class 1259 OID 30209) +-- Name: IX_JobDepartments_Job; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE UNIQUE INDEX "IX_JobDepartments_Job" ON public."JobDepartments" USING btree ("Job"); + + +-- +-- TOC entry 4793 (class 1259 OID 30198) +-- Name: IX_PlayerProfiles_PlayerDataId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_PlayerProfiles_PlayerDataId" ON public."PlayerProfiles" USING btree ("PlayerDataId"); + + +-- +-- TOC entry 4794 (class 1259 OID 30199) +-- Name: IX_PlayerProfiles_PlayerGuid; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE UNIQUE INDEX "IX_PlayerProfiles_PlayerGuid" ON public."PlayerProfiles" USING btree ("PlayerGuid"); + + +-- +-- TOC entry 4770 (class 1259 OID 30245) +-- Name: IX_Players_EffectiveJobId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Players_EffectiveJobId" ON public."Players" USING btree ("EffectiveJobId"); + + +-- +-- TOC entry 4771 (class 1259 OID 30235) +-- Name: IX_Players_ParticipantId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Players_ParticipantId" ON public."Players" USING btree ("ParticipantId"); + + +-- +-- TOC entry 4772 (class 1259 OID 30084) +-- Name: IX_Players_PlayerIcName; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Players_PlayerIcName" ON public."Players" USING btree ("PlayerIcName"); + + +-- +-- TOC entry 4806 (class 1259 OID 30222) +-- Name: IX_ReplayParticipants_PlayerGuid_ReplayId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE UNIQUE INDEX "IX_ReplayParticipants_PlayerGuid_ReplayId" ON public."ReplayParticipants" USING btree ("PlayerGuid", "ReplayId"); + + +-- +-- TOC entry 4807 (class 1259 OID 30223) +-- Name: IX_ReplayParticipants_ReplayId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_ReplayParticipants_ReplayId" ON public."ReplayParticipants" USING btree ("ReplayId"); + + +-- +-- TOC entry 4808 (class 1259 OID 30239) +-- Name: IX_ReplayParticipants_Username; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_ReplayParticipants_Username" ON public."ReplayParticipants" USING btree ("Username"); + + +-- +-- TOC entry 4763 (class 1259 OID 30078) +-- Name: IX_Replays_Gamemode; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Replays_Gamemode" ON public."Replays" USING btree ("Gamemode"); + + +-- +-- TOC entry 4764 (class 1259 OID 30079) +-- Name: IX_Replays_Map; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Replays_Map" ON public."Replays" USING btree ("Map"); + + +-- +-- TOC entry 4765 (class 1259 OID 30097) +-- Name: IX_Replays_RoundEndTextSearchVector; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Replays_RoundEndTextSearchVector" ON public."Replays" USING gin ("RoundEndTextSearchVector"); + + +-- +-- TOC entry 4766 (class 1259 OID 30081) +-- Name: IX_Replays_ServerId; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Replays_ServerId" ON public."Replays" USING btree ("ServerId"); + + +-- +-- TOC entry 4767 (class 1259 OID 30082) +-- Name: IX_Replays_ServerName; Type: INDEX; Schema: public; Owner: postgres +-- + +CREATE INDEX "IX_Replays_ServerName" ON public."Replays" USING btree ("ServerName"); + + +-- +-- TOC entry 4813 (class 2606 OID 30114) +-- Name: Accounts FK_Accounts_AccountSettings_SettingsId; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Accounts" + ADD CONSTRAINT "FK_Accounts_AccountSettings_SettingsId" FOREIGN KEY ("SettingsId") REFERENCES public."AccountSettings"("Id") ON DELETE CASCADE; + + +-- +-- TOC entry 4816 (class 2606 OID 30178) +-- Name: CharacterData FK_CharacterData_PlayerProfiles_CollectedPlayerDataPlayerGuid; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."CharacterData" + ADD CONSTRAINT "FK_CharacterData_PlayerProfiles_CollectedPlayerDataPlayerGuid" FOREIGN KEY ("CollectedPlayerDataPlayerGuid") REFERENCES public."PlayerProfiles"("PlayerGuid"); + + +-- +-- TOC entry 4814 (class 2606 OID 30127) +-- Name: HistoryEntry FK_HistoryEntry_Accounts_AccountId; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."HistoryEntry" + ADD CONSTRAINT "FK_HistoryEntry_Accounts_AccountId" FOREIGN KEY ("AccountId") REFERENCES public."Accounts"("Id"); + + +-- +-- TOC entry 4817 (class 2606 OID 30191) +-- Name: JobCountData FK_JobCountData_PlayerProfiles_CollectedPlayerDataPlayerGuid; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."JobCountData" + ADD CONSTRAINT "FK_JobCountData_PlayerProfiles_CollectedPlayerDataPlayerGuid" FOREIGN KEY ("CollectedPlayerDataPlayerGuid") REFERENCES public."PlayerProfiles"("PlayerGuid"); + + +-- +-- TOC entry 4815 (class 2606 OID 30165) +-- Name: PlayerProfiles FK_PlayerProfiles_PlayerData_PlayerDataId; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."PlayerProfiles" + ADD CONSTRAINT "FK_PlayerProfiles_PlayerData_PlayerDataId" FOREIGN KEY ("PlayerDataId") REFERENCES public."PlayerData"("Id") ON DELETE CASCADE; + + +-- +-- TOC entry 4811 (class 2606 OID 30246) +-- Name: Players FK_Players_JobDepartments_EffectiveJobId; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Players" + ADD CONSTRAINT "FK_Players_JobDepartments_EffectiveJobId" FOREIGN KEY ("EffectiveJobId") REFERENCES public."JobDepartments"("Id"); + + +-- +-- TOC entry 4812 (class 2606 OID 30240) +-- Name: Players FK_Players_ReplayParticipants_ParticipantId; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."Players" + ADD CONSTRAINT "FK_Players_ReplayParticipants_ParticipantId" FOREIGN KEY ("ParticipantId") REFERENCES public."ReplayParticipants"("Id") ON DELETE CASCADE; + + +-- +-- TOC entry 4818 (class 2606 OID 30217) +-- Name: ReplayParticipants FK_ReplayParticipants_Replays_ReplayId; Type: FK CONSTRAINT; Schema: public; Owner: postgres +-- + +ALTER TABLE ONLY public."ReplayParticipants" + ADD CONSTRAINT "FK_ReplayParticipants_Replays_ReplayId" FOREIGN KEY ("ReplayId") REFERENCES public."Replays"("Id") ON DELETE CASCADE; + + +-- Completed on 2024-08-26 03:37:02 + +-- +-- PostgreSQL database dump complete +-- + diff --git a/Tools/test_pages_for_errors.py b/Tools/test_pages_for_errors.py new file mode 100644 index 0000000..2851444 --- /dev/null +++ b/Tools/test_pages_for_errors.py @@ -0,0 +1,71 @@ +import asyncio +import subprocess +import time +import signal +import os +from pyppeteer import launch + +async def run_tests(): + process = subprocess.Popen( + ["dotnet", "run", "--no-build", "--project", "./ReplayBrowser/ReplayBrowser.csproj", "--configuration", "Testing"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + preexec_fn=os.setsid, + ) + + error_found = {"value": False} + + try: + print("Waiting for the application to start...") + await asyncio.sleep(20) + + # Start the browser + browser = await launch(headless=True) + page = await browser.newPage() + + urls = [ + "http://localhost:5000/", # Home page + "http://localhost:5000/privacy", # Privacy page + "http://localhost:5000/contact", # Contact page + "http://localhost:5000/leaderboard", # Leaderboard page + "http://localhost:5000/player/aac26166-139a-4163-8aa9-ad2a059a427d", # Player page (no redaction) + "http://localhost:5000/player/8ced134c-8731-4087-bed3-107d59af1a11", # Player page (redacted) + "http://localhost:5000/downloads", # Downloads page + "http://localhost:5000/changelog", # Changelog page + "http://localhost:5000/replay/3", # Replay page + ] + + for url in urls: + try: + print(f"Visiting {url}") + await page.goto(url) + await asyncio.sleep(3) + await page.waitForSelector('body', timeout=5000) + + exception_elements = await page.querySelectorAll('pre.rawExceptionStackTrace') # ASP.NET Core error dev page element + if exception_elements: + # Get error message + error_message = await page.evaluate('(element) => element.textContent', exception_elements[0]) + print(f"Error found on {url}: {error_message}") + error_found["value"] = True + else: + print(f"No errors found") + + except Exception as e: + print(f"Error visiting {url}: {e}") + error_found["value"] = True + + await browser.close() + + if error_found["value"]: + raise Exception("Test failed due to console errors or exceptions") + + finally: + print("Stopping the ASP.NET application...") + try: + os.killpg(os.getpgid(process.pid), signal.SIGTERM) + except Exception as e: + print(f"Error stopping the application: {e}") + +if __name__ == "__main__": + asyncio.run(run_tests())