Skip to content

Commit 6c19323

Browse files
committed
Merge branch 'dedicated-servers'
2 parents 1273777 + bb850e9 commit 6c19323

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+915
-400
lines changed

.github/workflows/build.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ jobs:
4848
run: MSBuild.exe .\\SML\\FactoryGame.sln /p:Configuration="Development Editor" /p:Platform="Win64" /t:"Games\FactoryGame"
4949

5050
- name: Package SML Mod
51-
run: .\\ue\\Engine\\Build\\BatchFiles\\RunUAT.bat -ScriptsForProject="$Env:GITHUB_WORKSPACE\\SML\\FactoryGame.uproject" PackagePlugin -Project="$Env:GITHUB_WORKSPACE\\SML\\FactoryGame.uproject" -dlcname=SML -build -clientconfig=Shipping -serverconfig=Shipping -platform=Win64 -nocompileeditor -installed
51+
run: .\\ue\\Engine\\Build\\BatchFiles\\RunUAT.bat -ScriptsForProject="$Env:GITHUB_WORKSPACE\\SML\\FactoryGame.uproject" PackagePlugin -Project="$Env:GITHUB_WORKSPACE\\SML\\FactoryGame.uproject" -dlcname=SML -build -server -clientconfig=Shipping -serverconfig=Shipping -platform=Win64 -serverplatform=Win64+Linux -nocompileeditor -installed
5252

5353
- name: Archive SML artifact
5454
uses: actions/upload-artifact@v2
5555
if: ${{ github.event_name == 'push' }}
5656
with:
5757
name: sml
58-
path: SML\\Saved\\ArchivedPlugins\\SML\\SML-Windows.zip
58+
path: SML\\Saved\\ArchivedPlugins\\SML\\*.zip

FactoryGame.uproject

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,5 +274,13 @@
274274
"Win64",
275275
"Linux",
276276
"Windows"
277-
]
277+
],
278+
"PreBuildSteps": {
279+
"Win64": [
280+
"powershell -Command \"$file = '$(ProjectDir)\\Plugins\\Wwise\\Source\\AkAudio\\Classes\\OcclusionObstructionService\\AkOcclusionObstructionService.h'; if (Test-Path $file) { if (!(Select-String -Path $file -Pattern 'class AKAUDIO_API AkOcclusionObstructionService' -SimpleMatch -Quiet)) { (Get-Content $file) -replace 'class AkOcclusionObstructionService', 'class AKAUDIO_API AkOcclusionObstructionService' | Out-File -encoding UTF8 $file } }\""
281+
],
282+
"Linux": [
283+
"if ! grep -q 'class AKAUDIO_API AkOcclusionObstructionService' $(ProjectDir)/Plugins/Wwise/Source/AkAudio/Classes/OcclusionObstructionService/AkOcclusionObstructionService.h; then sed -i 's/class AkOcclusionObstructionService/class AKAUDIO_API AkOcclusionObstructionService/' $(ProjectDir)/Plugins/Wwise/Source/AkAudio/Classes/OcclusionObstructionService/AkOcclusionObstructionService.h; fi"
284+
]
285+
}
278286
}

Mods/Alpakit/Source/Alpakit.Automation/PackagePlugin.cs

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,18 @@
66
using EpicGames.Core;
77
using UnrealBuildTool;
88
using AutomationScripts;
9+
using Microsoft.Extensions.Logging;
10+
using UnrealBuildBase;
911

1012
namespace Alpakit.Automation;
1113

1214
public class PackagePlugin : BuildCookRun
1315
{
1416
public override void ExecuteBuild()
1517
{
18+
var mergeArchive = ParseParam("merge");
19+
Logger.LogWarning($"Merge archive: {mergeArchive}");
20+
1621
var projectParams = SetupParams();
1722
projectParams.PreModifyDeploymentContextCallback = (ProjectParams, SC) =>
1823
{
@@ -36,6 +41,11 @@ public override void ExecuteBuild()
3641
ArchiveStagedPlugin(projectParams, SC);
3742
}
3843

44+
if (mergeArchive)
45+
{
46+
ArchiveMergedStagedPlugin(projectParams, deploymentContexts);
47+
}
48+
3949
foreach (var SC in deploymentContexts)
4050
{
4151
var copyToGameDirectory = ParseOptionalDirectoryReferenceParam($"CopyToGameDirectory_{SC.FinalCookPlatform}");
@@ -107,26 +117,65 @@ private static void DeployStagedPlugin(ProjectParams ProjectParams, DeploymentCo
107117

108118
private static void ArchiveStagedPlugin(ProjectParams ProjectParams, DeploymentContext SC)
109119
{
110-
// Plugins will be archived under <Project>/Saved/ArchivedPlugins/<DLCName>
111-
var baseArchiveDirectory = CombinePaths(SC.ProjectRoot.FullName, "Saved", "ArchivedPlugins");
112-
var archiveDirectory = CombinePaths(baseArchiveDirectory, ProjectParams.DLCFile.GetFileNameWithoutAnyExtensions());
113-
114-
CreateDirectory(archiveDirectory);
120+
var archiveDirectory = GetArchivedPluginDirectory(ProjectParams);
115121

116122
var dlcName = ProjectParams.DLCFile.GetFileNameWithoutAnyExtensions();
117123

118124
var zipFileName = $"{dlcName}-{SC.FinalCookPlatform}.zip";
119-
120-
var zipFilePath = CombinePaths(archiveDirectory, zipFileName);
121-
122-
if (FileExists(zipFilePath))
123-
DeleteFile(zipFilePath);
124125

125126
// We only want to archive the staged files of the plugin, not the entire stage directory
126127
var stagedPluginDirectory = Project.ApplyDirectoryRemap(SC, SC.GetStagedFileLocation(ProjectParams.DLCFile));
127128
var fullStagedPluginDirectory = DirectoryReference.Combine(SC.StageDirectory, stagedPluginDirectory.Directory.Name);
129+
130+
CreateZipFromDirectory(fullStagedPluginDirectory, FileReference.Combine(archiveDirectory, zipFileName));
131+
}
132+
133+
private static void ArchiveMergedStagedPlugin(ProjectParams ProjectParams, List<DeploymentContext> DeploymentContexts)
134+
{
135+
var archiveDirectory = GetArchivedPluginDirectory(ProjectParams);
136+
137+
var dlcName = ProjectParams.DLCFile.GetFileNameWithoutAnyExtensions();
128138

129-
ZipFile.CreateFromDirectory(fullStagedPluginDirectory.FullName, zipFilePath);
139+
var zipFileName = $"{dlcName}.zip";
140+
141+
// We only want to archive the staged files of the plugin, not the entire stage directory
142+
var mergedTempDir = DirectoryReference.Combine(ProjectParams.DLCFile.Directory, "Saved", "ArchiveMerging");
143+
try
144+
{
145+
if (DirectoryReference.Exists(mergedTempDir))
146+
DirectoryReference.Delete(mergedTempDir, true);
147+
DirectoryReference.CreateDirectory(mergedTempDir);
148+
foreach (var SC in DeploymentContexts)
149+
{
150+
var stagedPluginDirectory =
151+
Project.ApplyDirectoryRemap(SC, SC.GetStagedFileLocation(ProjectParams.DLCFile));
152+
var fullStagedPluginDirectory =
153+
DirectoryReference.Combine(SC.StageDirectory, stagedPluginDirectory.Directory.Name);
154+
CopyDirectory_NoExceptions(fullStagedPluginDirectory, DirectoryReference.Combine(mergedTempDir, SC.FinalCookPlatform));
155+
}
156+
157+
CreateZipFromDirectory(mergedTempDir, FileReference.Combine(archiveDirectory, zipFileName));
158+
}
159+
finally
160+
{
161+
DirectoryReference.Delete(mergedTempDir, true);
162+
}
163+
}
164+
165+
private static DirectoryReference GetArchivedPluginDirectory(ProjectParams ProjectParams)
166+
{
167+
// Plugins will be archived under <Project>/Saved/ArchivedPlugins/<DLCName>
168+
return DirectoryReference.Combine(ProjectParams.RawProjectPath.Directory, "Saved", "ArchivedPlugins", ProjectParams.DLCFile.GetFileNameWithoutAnyExtensions());
169+
}
170+
171+
private static void CreateZipFromDirectory(DirectoryReference SourceDirectory, FileReference DestinationFile)
172+
{
173+
CreateDirectory(DestinationFile.Directory);
174+
175+
if (FileReference.Exists(DestinationFile))
176+
FileReference.Delete(DestinationFile);
177+
178+
ZipFile.CreateFromDirectory(SourceDirectory.FullName, DestinationFile.FullName);
130179
}
131180

132181
private static string GetPluginPathRelativeToStageRoot(ProjectParams ProjectParams)

Mods/Alpakit/Source/Alpakit/Private/Alpakit.cpp

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@
99
#include "ISettingsSection.h"
1010
#include "LevelEditor.h"
1111
#include "IPluginBrowser.h"
12+
#include "UATHelper/Public/IUATHelperModule.h"
1213
#include "ModWizardDefinition.h"
14+
#include "ModTargetsConfig.h"
1315
#include "SAlpakitLogTabContent.h"
1416

1517
static const FName AlpakitTabName("Alpakit");
@@ -124,7 +126,30 @@ void FAlpakitModule::ShutdownModule() {
124126
FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(AlpakitLogTabName);
125127
}
126128

127-
void FAlpakitModule::PackageMods(TArray<TSharedRef<IPlugin>> Mods) {
129+
TSharedRef<FAlpakitProfile> MakeDevelopmentProfileForMod(TSharedRef<IPlugin> Mod) {
130+
TSharedRef<FAlpakitProfile> Profile = MakeShared<FAlpakitProfile>(Mod->GetName());
131+
132+
Profile->bBuild = Mod->GetDescriptor().Modules.Num() > 0;
133+
134+
UAlpakitSettings* Settings = UAlpakitSettings::Get();
135+
136+
Profile->BuildConfiguration = Settings->GetBuildConfiguration();
137+
138+
for (auto [CookedPlatform, TargetSetting] : Settings->GetPlatformTargetSettings()) {
139+
if (TargetSetting.bEnabled) {
140+
Profile->CookedPlatforms.Add(CookedPlatform);
141+
if (TargetSetting.bCopyModsToGame) {
142+
FAlpakitProfileGameInfo& GameInfo = Profile->PlatformGameInfo.FindOrAdd(CookedPlatform);
143+
GameInfo.bCopyToGame = true;
144+
GameInfo.GamePath = TargetSetting.SatisfactoryGamePath;
145+
}
146+
}
147+
}
148+
149+
return Profile;
150+
}
151+
152+
void FAlpakitModule::PackageModsDevelopment(TArray<TSharedRef<IPlugin>> Mods) {
128153
if (Mods.Num() == 0) {
129154
return;
130155
}
@@ -134,28 +159,47 @@ void FAlpakitModule::PackageMods(TArray<TSharedRef<IPlugin>> Mods) {
134159
UAlpakitSettings* Settings = UAlpakitSettings::Get();
135160

136161
for (TSharedRef<IPlugin> Mod : Mods) {
137-
TSharedRef<FAlpakitProfile> Profile = MakeShared<FAlpakitProfile>(Mod->GetName());
138-
139-
Profile->bBuild = Mod->GetDescriptor().Modules.Num() > 0;
162+
ProfilesToPackage.Add(MakeDevelopmentProfileForMod(Mod));
163+
}
140164

141-
Profile->BuildConfiguration = Settings->GetBuildConfiguration();
142-
// Profile->CookedPlatforms = Settings->CookPlatforms;
143-
Profile->CookedPlatforms = {TEXT("Windows")}; // Only Windows is allowed for now
165+
TSharedRef<FAlpakitProfile> LastProfile = ProfilesToPackage.Last();
144166

145-
if (Settings->bCopyModsToGame) {
146-
FAlpakitProfileGameInfo& GameInfo = Profile->PlatformGameInfo.FindOrAdd(TEXT("Windows"));
147-
GameInfo.bCopyToGame = true;
148-
GameInfo.GamePath = Settings->SatisfactoryGamePath.Path;
167+
for (auto [CookedPlatform, TargetSetting] : Settings->GetPlatformTargetSettings()) {
168+
if (TargetSetting.bEnabled) {
169+
if (TargetSetting.bLaunchGame) {
170+
FAlpakitProfileGameInfo& GameInfo = LastProfile->PlatformGameInfo.FindOrAdd(CookedPlatform);
171+
GameInfo.bStartGame = true;
172+
GameInfo.StartGameType = TargetSetting.LaunchGameType;
173+
}
149174
}
150-
151-
ProfilesToPackage.Add(Profile);
152175
}
153176

154-
TSharedRef<FAlpakitProfile> LastProfile = ProfilesToPackage.Last();
177+
PackageMods(ProfilesToPackage);
178+
}
179+
180+
TSharedRef<FAlpakitProfile> MakeReleaseProfileForMod(TSharedRef<IPlugin> Mod) {
181+
TSharedRef<FAlpakitProfile> Profile = MakeShared<FAlpakitProfile>(Mod->GetName());
182+
183+
Profile->bBuild = Mod->GetDescriptor().Modules.Num() > 0;
184+
Profile->BuildConfiguration = EBuildConfiguration::Shipping;
185+
186+
Profile->bMergeArchive = true;
187+
188+
FModTargetsConfig TargetsConfig(Mod);
189+
Profile->CookedPlatforms.Append(TargetsConfig.GetCookedPlatforms());
190+
191+
return Profile;
192+
}
155193

156-
if (Settings->LaunchGameAfterPacking != EAlpakitStartGameType::NONE) {
157-
FAlpakitProfileGameInfo& GameInfo = LastProfile->PlatformGameInfo.FindOrAdd(TEXT("Windows"));
158-
GameInfo.StartGameType = Settings->LaunchGameAfterPacking;
194+
void FAlpakitModule::PackageModsRelease(TArray<TSharedRef<IPlugin>> Mods) {
195+
if (Mods.Num() == 0) {
196+
return;
197+
}
198+
199+
TArray<TSharedRef<FAlpakitProfile>> ProfilesToPackage;
200+
201+
for (TSharedRef<IPlugin> Mod : Mods) {
202+
ProfilesToPackage.Add(MakeReleaseProfileForMod(Mod));
159203
}
160204

161205
PackageMods(ProfilesToPackage);
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#include "AlpakitEditModDialog.h"
2+
3+
#include "ISourceControlModule.h"
4+
#include "ISourceControlProvider.h"
5+
#include "ISourceControlOperation.h"
6+
#include "ISourceControlState.h"
7+
#include "ModMetadataObject.h"
8+
#include "SourceControlOperations.h"
9+
10+
#define LOCTEXT_NAMESPACE "AlpakitEditMod"
11+
12+
void SAlpakitEditModDialog::Construct(const FArguments& InArgs, TSharedRef<IPlugin> InMod) {
13+
Mod = InMod;
14+
15+
// Construct the plugin metadata object using the descriptor for this plugin
16+
MetadataObject = NewObject<UModMetadataObject>();
17+
MetadataObject->TargetIconPath = Mod->GetBaseDir() / TEXT("Resources/Icon128.png");
18+
MetadataObject->PopulateFromDescriptor(Mod->GetDescriptor());
19+
MetadataObject->AddToRoot();
20+
21+
// Create a property view
22+
FPropertyEditorModule& EditModule = FModuleManager::Get().GetModuleChecked<FPropertyEditorModule>("PropertyEditor");
23+
EditModule.RegisterCustomClassLayout(UModMetadataObject::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FModMetadataCustomization::MakeInstance));
24+
TSharedRef<IDetailsView> PropertyView = EditModule.CreateDetailView(FDetailsViewArgs(false, false, false, FDetailsViewArgs::ActorsUseNameArea, true));
25+
PropertyView->SetObject(MetadataObject, true);
26+
27+
SWindow::Construct(SWindow::FArguments()
28+
.ClientSize(FVector2D(800.0f, 700.0f))
29+
.Title(FText::Format(LOCTEXT("ModMetadata", "{0} ({1}) Properties"), FText::FromString(Mod->GetFriendlyName()), FText::FromString(Mod->GetName())))
30+
.Content()
31+
[
32+
SNew(SBorder)
33+
.Padding(FMargin(8.0f, 8.0f))
34+
[
35+
SNew(SVerticalBox)
36+
37+
+ SVerticalBox::Slot()
38+
.Padding(5)
39+
[
40+
PropertyView
41+
]
42+
43+
+ SVerticalBox::Slot()
44+
.AutoHeight()
45+
.Padding(5)
46+
.HAlign(HAlign_Right)
47+
[
48+
SNew(SButton)
49+
.ContentPadding(FMargin(20.0f, 2.0f))
50+
.Text(LOCTEXT("OkButtonLabel", "Ok"))
51+
.OnClicked(this, &SAlpakitEditModDialog::OnOkClicked)
52+
]
53+
]
54+
]
55+
);
56+
}
57+
58+
FReply SAlpakitEditModDialog::OnOkClicked() {
59+
FPluginDescriptor OldDescriptor = Mod->GetDescriptor();
60+
61+
// Update the descriptor with the new metadata
62+
FPluginDescriptor NewDescriptor = OldDescriptor;
63+
MetadataObject->CopyIntoDescriptor(NewDescriptor);
64+
MetadataObject->RemoveFromRoot();
65+
66+
// Close the properties window
67+
RequestDestroyWindow();
68+
69+
// Write both to strings
70+
FString OldText;
71+
OldDescriptor.Write(OldText);
72+
FString NewText;
73+
NewDescriptor.Write(NewText);
74+
if(OldText.Compare(NewText, ESearchCase::CaseSensitive) != 0)
75+
{
76+
FString DescriptorFileName = Mod->GetDescriptorFileName();
77+
78+
// First attempt to check out the file if SCC is enabled
79+
ISourceControlModule& SourceControlModule = ISourceControlModule::Get();
80+
if(SourceControlModule.IsEnabled())
81+
{
82+
ISourceControlProvider& SourceControlProvider = SourceControlModule.GetProvider();
83+
TSharedPtr<ISourceControlState, ESPMode::ThreadSafe> SourceControlState = SourceControlProvider.GetState(DescriptorFileName, EStateCacheUsage::ForceUpdate);
84+
if(SourceControlState.IsValid() && SourceControlState->CanCheckout())
85+
{
86+
SourceControlProvider.Execute(ISourceControlOperation::Create<FCheckOut>(), DescriptorFileName);
87+
}
88+
}
89+
90+
// Write to the file and update the in-memory metadata
91+
FText FailReason;
92+
if(!Mod->UpdateDescriptor(NewDescriptor, FailReason))
93+
{
94+
FMessageDialog::Open(EAppMsgType::Ok, FailReason);
95+
}
96+
}
97+
return FReply::Handled();
98+
}
99+
100+
#undef LOCTEXT_NAMESPACE

0 commit comments

Comments
 (0)