summaryrefslogtreecommitdiff
path: root/build/smapi.targets
blob: ea0cfffb991c632d04e4d66e385ab1dcddc948c0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <!--*********************************************
  ** Define build tasks used below
  **********************************************-->
  <!--######
  ## create a release zip file for a mod (CodeTaskFactory only available on Windows?)
  #######-->
  <UsingTask TaskName="CreateModReleaseZip" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" Condition="'$(OS)' == 'Windows_NT'">
    <ParameterGroup>
      <ModName ParameterType="System.String" Required="true" />
      <Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
      <OutputFolderPath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Reference Include="System.IO" />
      <Reference Include="System.IO.Compression" />
      <Using Namespace="System.IO" />
      <Using Namespace="System.IO.Compression" />
      <Code Type="Fragment" Language="cs">
        <![CDATA[
        try
        {
           // create output path if needed
           Directory.CreateDirectory(OutputFolderPath);

           // clear old zip file if present
           string zipPath = Path.Combine(OutputFolderPath, ModName + ".zip");
           if (File.Exists(zipPath))
              File.Delete(zipPath);

           // create zip file
           using (Stream zipStream = new FileStream(zipPath, FileMode.Create, FileAccess.Write))
           using (ZipArchive archive = new ZipArchive(zipStream, ZipArchiveMode.Create))
           {
              foreach (ITaskItem file in Files)
              {
                 // get file info
                 string filePath = file.ItemSpec;
                 string entryName = file.GetMetadata("RecursiveDir") + file.GetMetadata("Filename") + file.GetMetadata("Extension");
                 if (new FileInfo(filePath).Directory.Name.Equals("i18n", StringComparison.InvariantCultureIgnoreCase))
                    entryName = Path.Combine("i18n", entryName);

                 // add to zip
                 using (Stream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
                 using (Stream fileStreamInZip = archive.CreateEntry(entryName).Open())
                 {
                    fileStream.CopyTo(fileStreamInZip);
                 }
              }
           }
           
           return true;
        }
        catch (Exception ex)
        {
          Log.LogErrorFromException(ex);
          return false;
        }
        ]]>
      </Code>
    </Task>
  </UsingTask>


  <!--*********************************************
  ** Find the basic mod metadata
  **********************************************-->
  <!--######
  ## import developer's custom settings (if any)
  #######-->
  <Import Condition="$(OS) != 'Windows_NT' AND Exists('$(HOME)\stardewvalley.targets')" Project="$(HOME)\stardewvalley.targets" />
  <Import Condition="$(OS) == 'Windows_NT' AND Exists('$(USERPROFILE)\stardewvalley.targets')" Project="$(USERPROFILE)\stardewvalley.targets" />

  <!--######
  ## find platform + game path
  #######-->
  <Choose>
    <When Condition="$(OS) == 'Unix' OR $(OS) == 'OSX'">
      <PropertyGroup>
        <!-- Linux -->
        <GamePath Condition="!Exists('$(GamePath)')">$(HOME)/GOG Games/Stardew Valley/game</GamePath>
        <GamePath Condition="!Exists('$(GamePath)')">$(HOME)/.local/share/Steam/steamapps/common/Stardew Valley</GamePath>

        <!-- Mac (may be 'Unix' or 'OSX') -->
        <GamePath Condition="!Exists('$(GamePath)')">/Applications/Stardew Valley.app/Contents/MacOS</GamePath>
        <GamePath Condition="!Exists('$(GamePath)')">$(HOME)/Library/Application Support/Steam/steamapps/common/Stardew Valley/Contents/MacOS</GamePath>
      </PropertyGroup>
    </When>
    <When Condition="$(OS) == 'Windows_NT'">
      <PropertyGroup>
        <GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\GalaxyClient\Games\Stardew Valley</GamePath>
        <GamePath Condition="!Exists('$(GamePath)')">C:\Program Files (x86)\Steam\steamapps\common\Stardew Valley</GamePath>
        <GamePath Condition="!Exists('$(GamePath)')">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\GOG.com\Games\1453375253', 'PATH', null, RegistryView.Registry32))</GamePath>
        <GamePath Condition="!Exists('$(GamePath)')">$([MSBuild]::GetRegistryValueFromView('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\Steam App 413150', 'InstallLocation', null, RegistryView.Registry64, RegistryView.Registry32))</GamePath>
      </PropertyGroup>
    </When>
  </Choose>


  <!--*********************************************
  ** Inject the assembly references and debugging configuration
  **********************************************-->
  <Choose>
    <When Condition="$(OS) == 'Windows_NT'">
      <!-- references -->
      <ItemGroup>
        <Reference Include="Microsoft.Xna.Framework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
          <Private>false</Private>
        </Reference>
        <Reference Include="Microsoft.Xna.Framework.Game, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
          <Private>false</Private>
        </Reference>
        <Reference Include="Microsoft.Xna.Framework.Graphics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
          <Private>false</Private>
        </Reference>
        <Reference Include="Microsoft.Xna.Framework.Xact, Version=4.0.0.0, Culture=neutral, PublicKeyToken=842cf8be1de50553, processorArchitecture=x86">
          <Private>false</Private>
        </Reference>
        <Reference Include="Stardew Valley">
          <HintPath>$(GamePath)\Stardew Valley.exe</HintPath>
          <Private>false</Private>
        </Reference>
        <Reference Include="StardewModdingAPI">
          <HintPath>$(GamePath)\StardewModdingAPI.exe</HintPath>
          <Private>false</Private>
        </Reference>
        <Reference Include="xTile, Version=2.0.4.0, Culture=neutral, processorArchitecture=x86">
          <HintPath>$(GamePath)\xTile.dll</HintPath>
          <Private>false</Private>
          <SpecificVersion>False</SpecificVersion>
        </Reference>
      </ItemGroup>

      <!-- launch game for debugging -->
      <PropertyGroup>
        <StartAction>Program</StartAction>
        <StartProgram>$(GamePath)\StardewModdingAPI.exe</StartProgram>
        <StartWorkingDirectory>$(GamePath)</StartWorkingDirectory>
      </PropertyGroup>
    </When>
    <Otherwise>
      <!-- references -->
      <ItemGroup>
        <Reference Include="MonoGame.Framework">
          <HintPath>$(GamePath)\MonoGame.Framework.dll</HintPath>
          <Private>false</Private>
          <SpecificVersion>False</SpecificVersion>
        </Reference>
        <Reference Include="StardewValley">
          <HintPath>$(GamePath)\StardewValley.exe</HintPath>
          <Private>false</Private>
        </Reference>
        <Reference Include="StardewModdingAPI">
          <HintPath>$(GamePath)\StardewModdingAPI.exe</HintPath>
          <Private>false</Private>
        </Reference>
        <Reference Include="xTile">
          <HintPath>$(GamePath)\xTile.dll</HintPath>
          <Private>false</Private>
        </Reference>
      </ItemGroup>
    </Otherwise>
  </Choose>


  <!--*********************************************
  ** Perform build logic
  **********************************************-->
  <!--######
  ## validate metadata before build
  #######-->
  <Target Name="BeforeBuild">
    <!-- show error for unknown platform -->
    <Error Condition="'$(OS)' != 'OSX' AND '$(OS)' != 'Unix' AND '$(OS)' != 'Windows_NT'" Text="The build config package doesn't recognise OS type '$(OS)'." />

    <!-- if game path is invalid, show one user-friendly error instead of a slew of reference errors -->
    <Error Condition="!Exists('$(GamePath)')" Text="Failed to find the game install path. See https://github.com/Pathoschild/Stardew.ModBuildConfig#troubleshoot for help." />
    <Error Condition="'$(OS)' == 'Windows_NT' AND !Exists('$(GamePath)\Stardew Valley.exe')" Text="Found a game folder at $(GamePath), but it doesn't contain Stardew Valley. You should delete this folder if it's empty." />
    <Error Condition="'$(OS)' != 'Windows_NT' AND !Exists('$(GamePath)\StardewValley.exe')" Text="Found a game folder at $(GamePath), but it doesn't contain Stardew Valley. You should delete this folder if it's empty." />
    <Error Condition="!Exists('$(GamePath)\StardewModdingAPI.exe')" Text="Found a game folder at $(GamePath), but it doesn't contain SMAPI." />
  </Target>

  <!--######
  ## Deploy files after build
  #######-->
  <Target Name="AfterBuild" Condition="'$(DeployModFolderName)' != '' OR '$(DeployModZipTo)' != ''">
    <!--collect file paths-->
    <PropertyGroup>
      <ModDeployPath>$(GamePath)\Mods\$(DeployModFolderName)</ModDeployPath>
      <DeployModZipTo Condition="'$(OS)' != 'Windows_NT'"><!--disable on Linux/Mac where CodeTaskFactory doesn't seem to be available--></DeployModZipTo>
    </PropertyGroup>
    <ItemGroup>
      <BuildFiles Include="$(TargetDir)\**\*.*" />
      <BuildFiles Include="$(ProjectDir)\manifest.json" Condition="'@(BuildFiles)' != '' AND EXISTS('$(ProjectDir)\manifest.json')" />
      <I18nFiles Include="$(ProjectDir)\i18n\*.json" Condition="'@(BuildFiles)' != '' AND EXISTS('$(ProjectDir)\i18n')" />
    </ItemGroup>

    <!--validate paths-->
    <Error Text="Could not deploy mod automatically because no build output was found." Condition="'@(BuildFiles)' == ''" />
    <Error Text="Could not deploy mod automatically because no manifest.json was found in the project or build output." Condition="!Exists('$(TargetDir)\manifest.json') AND !Exists('$(ProjectDir)\manifest.json')" />

    <!-- copy mod files into mod folder if <DeployModFolderName> property is set -->
    <Message Text="Deploying mod to $(ModDeployPath)..." Importance="high" Condition="'$(DeployModFolderName)' != ''" />
    <Copy SourceFiles="@(BuildFiles)" DestinationFolder="$(ModDeployPath)\%(RecursiveDir)" SkipUnchangedFiles="true" Condition="'$(DeployModFolderName)' != ''" />
    <Copy SourceFiles="@(I18nFiles)" DestinationFolder="$(ModDeployPath)\i18n" SkipUnchangedFiles="true" Condition="'$(DeployModFolderName)' != ''" />

    <!-- create release zip if <DeployModZipTo> property is set -->
    <Message Text="Generating mod release at $(DeployModZipTo)\$(MSBuildProjectName).zip..." Importance="high" Condition="'$(DeployModZipTo)' != ''" />
    <CreateModReleaseZip ModName="$(MSBuildProjectName)" Files="@(BuildFiles);@(I18nFiles)" OutputFolderPath="$(DeployModZipTo)" Condition="'$(DeployModZipTo)' != ''" />
  </Target>
</Project>