# Conflicts: # .github/workflows/publish.yml # Content.Client/Clothing/ClientClothingSystem.cs # Content.Client/Clothing/Systems/ChameleonClothingSystem.cs # Content.Client/Fax/UI/FaxWindow.xaml # Content.Client/Ghost/GhostSystem.cs # Content.Client/Holiday/HolidaySystem.cs # Content.Client/Humanoid/HumanoidAppearanceSystem.cs # Content.Client/Lobby/UI/Loadouts/LoadoutWindow.xaml.cs # Content.Client/Lobby/UI/LobbyGui.xaml # Content.Client/Lobby/UI/LobbyGui.xaml.cs # Content.Client/Mech/MechSystem.cs # Content.Client/Stealth/StealthSystem.cs # Content.Client/Weapons/Ranged/Systems/GunSystem.cs # Content.Server.Database/Migrations/Sqlite/SqliteServerDbContextModelSnapshot.cs # Content.Server/Bed/BedSystem.cs # Content.Server/Body/Systems/BodySystem.cs # Content.Server/Body/Systems/RespiratorSystem.cs # Content.Server/Cargo/Systems/CargoSystem.Orders.cs # Content.Server/Communications/CommunicationsConsoleComponent.cs # Content.Server/EntityEffects/Effects/AreaReactionEffect.cs # Content.Server/EntityEffects/Effects/MakeSentient.cs # Content.Server/EntityEffects/Effects/PlantMetabolism/PlantAdjustPests.cs # Content.Server/EntityEffects/Effects/PlantMetabolism/PlantAdjustToxins.cs # Content.Server/EntityEffects/Effects/PlantMetabolism/PlantAdjustWeeds.cs # Content.Server/EntityEffects/Effects/PlantMutateGases.cs # Content.Server/Fluids/EntitySystems/AbsorbentSystem.cs # Content.Server/GameTicking/GameTicker.Spawning.cs # Content.Server/GameTicking/Rules/NukeopsRuleSystem.cs # Content.Server/IoC/ServerContentIoC.cs # Content.Server/Nutrition/EntitySystems/FoodSystem.cs # Content.Server/Power/EntitySystems/PowerNetSystem.cs # Content.Server/Preferences/Managers/ServerPreferencesManager.cs # Content.Server/RoundEnd/RoundEndSystem.cs # Content.Server/Shuttles/Systems/EmergencyShuttleSystem.cs # Content.Server/Station/Systems/StationSpawningSystem.cs # Content.Server/VoiceMask/VoiceMaskSystem.cs # Content.Server/Weapons/Ranged/Systems/GunSystem.cs # Content.Shared/Bed/Components/HealOnBuckleComponent.cs # Content.Shared/Clothing/EntitySystems/ClothingSystem.cs # Content.Shared/EntityEffects/Effects/ExplosionReactionEffect.cs # Content.Shared/Inventory/InventorySystem.Relay.cs # Content.Shared/Item/ItemToggle/Components/ComponentTogglerComponent.cs # Content.Shared/Preferences/HumanoidCharacterProfile.cs # Content.Shared/Preferences/Loadouts/RoleLoadout.cs # Content.Shared/Weapons/Melee/SharedMeleeWeaponSystem.cs # Content.Shared/Wieldable/SharedWieldableSystem.cs # Resources/Audio/Machines/attributions.yml # Resources/Locale/en-US/_strings/atmos/plaque-component.ftl # Resources/Locale/en-US/_strings/chat/chat-channel.ftl # Resources/Locale/en-US/_strings/components/screen-component.ftl # Resources/Locale/en-US/_strings/inventory/components/slot-block-component.ftl # Resources/Locale/en-US/_strings/mass-media/news-discord.ftl # Resources/Locale/en-US/_strings/objectives/commands/stripall.ftl # Resources/Locale/en-US/_strings/salvage/job-board.ftl # Resources/Locale/en-US/_strings/ui/spray-painter-window.ftl # Resources/Locale/en-US/_strings/ui/turret-controls.ftl # Resources/Maps/_Sunrise/Station/box.yml # Resources/Prototypes/Access/misc.yml # Resources/Prototypes/Catalog/Fills/Boxes/emergency.yml # Resources/Prototypes/Catalog/Fills/Lockers/engineer.yml # Resources/Prototypes/Catalog/Fills/Lockers/heads.yml # Resources/Prototypes/Catalog/Fills/Lockers/service.yml # Resources/Prototypes/Catalog/Fills/Lockers/suit_storage.yml # Resources/Prototypes/Entities/Clothing/Head/helmets.yml # Resources/Prototypes/Entities/Clothing/Masks/masks.yml # Resources/Prototypes/Entities/Clothing/OuterClothing/hardsuits.yml # Resources/Prototypes/Entities/Markers/Spawners/mobs.yml # Resources/Prototypes/Entities/Mobs/Cyborgs/base_borg_chassis.yml # Resources/Prototypes/Entities/Mobs/NPCs/animals.yml # Resources/Prototypes/Entities/Mobs/NPCs/regalrat.yml # Resources/Prototypes/Entities/Mobs/NPCs/silicon.yml # Resources/Prototypes/Entities/Mobs/Player/dragon.yml # Resources/Prototypes/Entities/Mobs/Player/silicon.yml # Resources/Prototypes/Entities/Mobs/Species/arachnid.yml # Resources/Prototypes/Entities/Mobs/Species/moth.yml # Resources/Prototypes/Entities/Objects/Specific/Robotics/borg_modules.yml # Resources/Prototypes/Entities/Objects/Weapons/Guns/Shotguns/shotguns.yml # Resources/Prototypes/LootTables/suspicion_loot_table.yml # Resources/Prototypes/Reagents/Consumable/Drink/drinks.yml # Resources/Prototypes/Reagents/medicine.yml # Resources/Prototypes/Recipes/Lathes/Packs/science.yml # Resources/Prototypes/Recipes/Lathes/medical.yml # Resources/Prototypes/SoundCollections/NukeMusic.yml # Resources/ServerInfo/Guidebook/Cargo/Salvage.xml # Resources/Textures/Clothing/Hands/Gloves/KnuckleDusters/brassknuckleduster.rsi/equipped-OUTERCLOTHING-reptilian.png # Resources/Textures/Clothing/OuterClothing/Hardsuits/basic.rsi/meta.json # Resources/Textures/Clothing/OuterClothing/Suits/eva.rsi/meta.json # Resources/Textures/Clothing/OuterClothing/Suits/eva_emergency.rsi/meta.json # Resources/Textures/Clothing/OuterClothing/Suits/eva_prisoner.rsi/meta.json # Resources/Textures/Effects/speech.rsi/alien3.png # Resources/Textures/Effects/speech.rsi/alienroyal3.png # Resources/Textures/Effects/speech.rsi/default3.png # Resources/Textures/Effects/speech.rsi/guardian3.png # Resources/Textures/Effects/speech.rsi/holo3.png # Resources/Textures/Effects/speech.rsi/lawyer3.png # Resources/Textures/Effects/speech.rsi/lizard3.png # Resources/Textures/Effects/speech.rsi/meta.json # Resources/Textures/Effects/speech.rsi/moth3.png # Resources/Textures/Effects/speech.rsi/robot3.png # Resources/Textures/Effects/speech.rsi/slime3.png # Resources/Textures/Effects/speech.rsi/spider3.png # Resources/Textures/Effects/speech.rsi/syndibot3.png # Resources/Textures/Interface/Misc/job_icons.rsi/meta.json # Resources/Textures/Mobs/Silicon/chassis.rsi/meta.json # Resources/Textures/Mobs/Species/Reptilian/parts.rsi/head_f.png # Resources/Textures/Mobs/Species/Reptilian/parts.rsi/head_m.png # Resources/Textures/Objects/Misc/id_cards.rsi/meta.json # Resources/Textures/Structures/Doors/Airlocks/Glass/external.rsi/emergency_unlit.png # Resources/Textures/Structures/Piping/disposal.rsi/meta.json # Resources/Textures/Tiles/attributions.yml # Resources/Textures/Tiles/steel_dirty.png # Resources/migration.yml # runclient-Tools.bat # runclient.bat
230 lines
7.5 KiB
C#
230 lines
7.5 KiB
C#
using System.Diagnostics;
|
|
using System.IO.Compression;
|
|
using Robust.Packaging;
|
|
using Robust.Packaging.AssetProcessing;
|
|
using Robust.Packaging.AssetProcessing.Passes;
|
|
using Robust.Packaging.Utility;
|
|
using Robust.Shared.Timing;
|
|
|
|
namespace Content.Packaging;
|
|
|
|
public static class ServerPackaging
|
|
{
|
|
private static readonly List<PlatformReg> Platforms = new()
|
|
{
|
|
new PlatformReg("win-x64", "Windows", true),
|
|
new PlatformReg("win-arm64", "Windows", true),
|
|
new PlatformReg("linux-x64", "Linux", true),
|
|
new PlatformReg("linux-arm64", "Linux", true),
|
|
new PlatformReg("osx-x64", "MacOS", true),
|
|
new PlatformReg("osx-arm64", "MacOS", true),
|
|
// Non-default platforms (i.e. for Watchdog Git)
|
|
new PlatformReg("win-x86", "Windows", false),
|
|
new PlatformReg("linux-x86", "Linux", false),
|
|
new PlatformReg("linux-arm", "Linux", false),
|
|
new PlatformReg("freebsd-x64", "FreeBSD", false),
|
|
};
|
|
|
|
private static List<string> PlatformRids => Platforms
|
|
.Select(o => o.Rid)
|
|
.ToList();
|
|
|
|
private static List<string> PlatformRidsDefault => Platforms
|
|
.Where(o => o.BuildByDefault)
|
|
.Select(o => o.Rid)
|
|
.ToList();
|
|
|
|
private static readonly List<string> ServerContentAssemblies = new()
|
|
{
|
|
// Sunrise-Start
|
|
"Content.Sunrise.Interfaces.Shared",
|
|
"Content.Sunrise.Interfaces.Server",
|
|
// Sunrise-End
|
|
"Content.Server.Database",
|
|
"Content.Server",
|
|
"Content.Shared",
|
|
"Content.Shared.Database",
|
|
};
|
|
|
|
private static readonly List<string> ServerExtraAssemblies = new()
|
|
{
|
|
// Python script had Npgsql. though we want Npgsql.dll as well soooo
|
|
"Npgsql",
|
|
"Microsoft",
|
|
"Discord",
|
|
};
|
|
|
|
private static readonly List<string> ServerNotExtraAssemblies = new()
|
|
{
|
|
"Microsoft.CodeAnalysis",
|
|
};
|
|
|
|
private static readonly HashSet<string> BinSkipFolders = new()
|
|
{
|
|
// Roslyn localization files, screw em.
|
|
"cs",
|
|
"de",
|
|
"es",
|
|
"fr",
|
|
"it",
|
|
"ja",
|
|
"ko",
|
|
"pl",
|
|
"pt-BR",
|
|
"ru",
|
|
"tr",
|
|
"zh-Hans",
|
|
"zh-Hant"
|
|
};
|
|
|
|
public static async Task PackageServer(bool skipBuild, bool hybridAcz, IPackageLogger logger, string configuration, List<string>? platforms = null)
|
|
{
|
|
if (platforms == null)
|
|
{
|
|
platforms ??= PlatformRidsDefault;
|
|
}
|
|
|
|
if (hybridAcz)
|
|
{
|
|
// Hybrid ACZ involves a file "Content.Client.zip" in the server executable directory.
|
|
// Rather than hosting the client ZIP on the watchdog or on a separate server,
|
|
// Hybrid ACZ uses the ACZ hosting functionality to host it as part of the status host,
|
|
// which means that features such as automatic UPnP forwarding still work properly.
|
|
await ClientPackaging.PackageClient(skipBuild, configuration, logger);
|
|
}
|
|
|
|
// Good variable naming right here.
|
|
foreach (var platform in Platforms)
|
|
{
|
|
if (!platforms.Contains(platform.Rid))
|
|
continue;
|
|
|
|
await BuildPlatform(platform, skipBuild, hybridAcz, configuration, logger);
|
|
}
|
|
}
|
|
|
|
private static async Task BuildPlatform(PlatformReg platform, bool skipBuild, bool hybridAcz, string configuration, IPackageLogger logger)
|
|
{
|
|
logger.Info($"Building project for {platform.TargetOs}...");
|
|
|
|
if (!skipBuild)
|
|
{
|
|
await ProcessHelpers.RunCheck(new ProcessStartInfo
|
|
{
|
|
FileName = "dotnet",
|
|
ArgumentList =
|
|
{
|
|
"build",
|
|
Path.Combine("Content.Server", "Content.Server.csproj"),
|
|
"-c", configuration,
|
|
"--nologo",
|
|
"/v:m",
|
|
$"/p:TargetOs={platform.TargetOs}",
|
|
"/t:Rebuild",
|
|
"/p:FullRelease=true",
|
|
"/m"
|
|
}
|
|
});
|
|
|
|
await PublishClientServer(platform.Rid, platform.TargetOs, configuration);
|
|
}
|
|
|
|
logger.Info($"Packaging {platform.Rid} server...");
|
|
|
|
var sw = RStopwatch.StartNew();
|
|
{
|
|
await using var zipFile =
|
|
File.Open(Path.Combine("release", $"SS14.Server_{platform.Rid}.zip"), FileMode.Create, FileAccess.ReadWrite);
|
|
using var zip = new ZipArchive(zipFile, ZipArchiveMode.Update);
|
|
var writer = new AssetPassZipWriter(zip);
|
|
|
|
await WriteServerResources(platform, "", writer, logger, hybridAcz, default);
|
|
await writer.FinishedTask;
|
|
}
|
|
|
|
logger.Info($"Finished packaging server in {sw.Elapsed}");
|
|
}
|
|
|
|
private static async Task PublishClientServer(string runtime, string targetOs, string configuration)
|
|
{
|
|
await ProcessHelpers.RunCheck(new ProcessStartInfo
|
|
{
|
|
FileName = "dotnet",
|
|
ArgumentList =
|
|
{
|
|
"publish",
|
|
"--runtime", runtime,
|
|
"--no-self-contained",
|
|
"-c", configuration,
|
|
$"/p:TargetOs={targetOs}",
|
|
"/p:FullRelease=True",
|
|
"/m",
|
|
"RobustToolbox/Robust.Server/Robust.Server.csproj"
|
|
}
|
|
});
|
|
}
|
|
|
|
private static async Task WriteServerResources(
|
|
PlatformReg platform,
|
|
string contentDir,
|
|
AssetPass pass,
|
|
IPackageLogger logger,
|
|
bool hybridAcz,
|
|
CancellationToken cancel)
|
|
{
|
|
var graph = new RobustServerAssetGraph();
|
|
var passes = graph.AllPasses.ToList();
|
|
|
|
pass.Dependencies.Add(new AssetPassDependency(graph.Output.Name));
|
|
passes.Add(pass);
|
|
|
|
AssetGraph.CalculateGraph(passes, logger);
|
|
|
|
var inputPassCore = graph.InputCore;
|
|
var inputPassResources = graph.InputResources;
|
|
var contentAssemblies = new List<string>(ServerContentAssemblies);
|
|
|
|
// Additional assemblies that need to be copied such as EFCore.
|
|
var sourcePath = Path.Combine(contentDir, "bin", "Content.Server");
|
|
|
|
// Should this be an asset pass?
|
|
// For future archaeologists I just want audio rework to work and need the audio pass so
|
|
// just porting this as is from python.
|
|
foreach (var fullPath in Directory.EnumerateFiles(sourcePath, "*.*", SearchOption.AllDirectories))
|
|
{
|
|
var fileName = Path.GetFileNameWithoutExtension(fullPath);
|
|
|
|
if (!ServerNotExtraAssemblies.Any(o => fileName.StartsWith(o)) && ServerExtraAssemblies.Any(o => fileName.StartsWith(o)))
|
|
{
|
|
contentAssemblies.Add(fileName);
|
|
}
|
|
}
|
|
|
|
await RobustSharedPackaging.DoResourceCopy(
|
|
Path.Combine("RobustToolbox", "bin", "Server",
|
|
platform.Rid,
|
|
"publish"),
|
|
inputPassCore,
|
|
BinSkipFolders,
|
|
cancel: cancel);
|
|
|
|
await RobustSharedPackaging.WriteContentAssemblies(
|
|
inputPassResources,
|
|
contentDir,
|
|
"Content.Server",
|
|
contentAssemblies,
|
|
cancel: cancel);
|
|
|
|
await RobustServerPackaging.WriteServerResources(contentDir, inputPassResources, cancel);
|
|
|
|
if (hybridAcz)
|
|
{
|
|
inputPassCore.InjectFileFromDisk("Content.Client.zip", Path.Combine("release", "SS14.Client.zip"));
|
|
}
|
|
|
|
inputPassCore.InjectFinished();
|
|
inputPassResources.InjectFinished();
|
|
}
|
|
|
|
private readonly record struct PlatformReg(string Rid, string TargetOs, bool BuildByDefault);
|
|
}
|