nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 stdenv,
4 fetchFromGitHub,
5 fetchzip,
6 makeWrapper,
7 premake5,
8 writeShellApplication,
9 runCommandLocal,
10 symlinkJoin,
11 writeText,
12 imagemagick,
13 bzip2,
14 curl,
15 envsubst,
16 flac,
17 fmt,
18 freetype,
19 irrlicht,
20 libevent,
21 libgit2,
22 libGL,
23 libGLU,
24 libjpeg,
25 libpng,
26 libvorbis,
27 libX11,
28 libxkbcommon,
29 libXxf86vm,
30 mono,
31 nlohmann_json,
32 openal,
33 SDL2,
34 sqlite,
35 wayland,
36 egl-wayland,
37 zenity,
38 covers_url ? "https://pics.projectignis.org:2096/pics/cover/{}.jpg",
39 fields_url ? "https://pics.projectignis.org:2096/pics/field/{}.png",
40 # While ygoprodeck has higher quality images:
41 # 1. automated downloads for sims via their API are discouraged by the owner
42 # 2. images for prerelease cards are unavailable on their service
43 pics_url ? "https://pics.projectignis.org:2096/pics/{}.jpg",
44}:
45let
46 archLabel =
47 {
48 "x86_64-linux" = "x64";
49 "aarch64-linux" = "arm64";
50 }
51 .${stdenv.hostPlatform.system}
52 or (throw "${stdenv.hostPlatform.system} is an unsupported arch label for edopro");
53
54 maintainers = with lib.maintainers; [
55 OPNA2608
56 redhawk
57 ];
58
59 deps = import ./deps.nix;
60
61 edopro-src = fetchFromGitHub {
62 owner = "edo9300";
63 repo = "edopro";
64 rev = deps.edopro-rev;
65 fetchSubmodules = true;
66 hash = deps.edopro-hash;
67 };
68in
69let
70 assets = fetchzip {
71 url = "https://github.com/ProjectIgnis/edopro-assets/releases/download/${deps.edopro-version}/ProjectIgnis-EDOPro-${deps.edopro-version}-linux.tar.gz";
72 hash = deps.assets-hash;
73 };
74
75 irrlicht-edopro = stdenv.mkDerivation {
76 pname = "irrlicht-edopro";
77 version = deps.irrlicht-version;
78
79 src = fetchFromGitHub {
80 owner = "edo9300";
81 repo = "irrlicht1-8-4";
82 rev = deps.irrlicht-rev;
83 hash = deps.irrlicht-hash;
84 };
85
86 buildInputs = [
87 libGLU
88 libX11
89 libxkbcommon
90 libXxf86vm
91 wayland
92 ];
93
94 enableParallelBuilding = true;
95 buildFlags = [ "NDEBUG=1" ];
96 makeFlags = [
97 "-C"
98 "source/Irrlicht"
99 ];
100
101 installPhase = ''
102 runHook preInstall
103
104 install -Dm644 -t $out/lib lib/Linux/libIrrlicht.a
105 cp -r include $out/include
106
107 runHook postInstall
108 '';
109
110 meta = {
111 inherit (irrlicht.meta) description platforms;
112 homepage = "https://github.com/edo9300/irrlicht1-8-4";
113 license = lib.licenses.agpl3Plus;
114 inherit maintainers;
115 };
116 };
117
118 ocgcore =
119 let
120 # Refer to CORENAME EPRO_TEXT in <edopro>/gframe/dllinterface.cpp for this
121 ocgcoreName = lib.strings.concatStrings [
122 (lib.optionalString (!stdenv.hostPlatform.isWindows) "lib")
123 "ocgcore"
124 (
125 if stdenv.hostPlatform.isiOS then
126 "-ios"
127 else if stdenv.hostPlatform.isAndroid then
128 (
129 if stdenv.hostPlatform.isx86_64 then
130 "x64"
131 else if stdenv.hostPlatform.isx86_32 then
132 "x86"
133 else if stdenv.hostPlatform.isAarch64 then
134 "v8"
135 else if stdenv.hostPlatform.isAarch32 then
136 "v7"
137 else
138 throw "Don't know what platform suffix edopro expects for ocgcore on: ${stdenv.hostPlatform.system}"
139 )
140 else
141 lib.optionalString (stdenv.hostPlatform.isLinux && stdenv.hostPlatform.isAarch64) ".aarch64"
142 )
143 stdenv.hostPlatform.extensions.sharedLibrary
144 ];
145 in
146 stdenv.mkDerivation {
147 pname = "ocgcore-edopro";
148 version = deps.edopro-version;
149
150 src = edopro-src;
151 sourceRoot = "${edopro-src.name}/ocgcore";
152
153 nativeBuildInputs = [
154 premake5
155 ];
156
157 enableParallelBuilding = true;
158
159 buildFlags = [
160 "verbose=true"
161 "config=release"
162 "ocgcoreshared"
163 ];
164
165 makeFlags = [
166 "-C"
167 "build"
168 ];
169
170 # To make sure linking errors are discovered at build time, not when edopro runs into them during loading
171 env.NIX_LDFLAGS = "--unresolved-symbols=report-all";
172
173 installPhase = ''
174 runHook preInstall
175
176 install -Dm644 bin/release/*ocgcore*${stdenv.hostPlatform.extensions.sharedLibrary} $out/lib/${ocgcoreName}
177
178 runHook postInstall
179 '';
180
181 meta = {
182 description = "YGOPro script engine";
183 homepage = "https://github.com/edo9300/ygopro-core";
184 license = lib.licenses.agpl3Plus;
185 inherit maintainers;
186 platforms = lib.platforms.unix;
187 };
188 };
189
190 edopro = stdenv.mkDerivation {
191 pname = "edopro";
192 version = deps.edopro-version;
193
194 src = edopro-src;
195
196 nativeBuildInputs = [
197 makeWrapper
198 premake5
199 ];
200
201 buildInputs = [
202 bzip2
203 curl
204 flac
205 fmt
206 freetype
207 irrlicht-edopro
208 libevent
209 libgit2
210 libjpeg
211 libpng
212 libvorbis
213 nlohmann_json
214 openal
215 SDL2
216 sqlite
217 ];
218
219 # nixpkgs' gcc stack currently appears to not support LTO
220 # Override where bundled ocgcore get looked up in, so we can supply ours
221 # (can't use --prebuilt-core or let it build a core on its own without making core updates impossible)
222 postPatch = ''
223 substituteInPlace premake5.lua \
224 --replace-fail 'flags "LinkTimeOptimization"' 'removeflags "LinkTimeOptimization"'
225
226 substituteInPlace gframe/game.cpp \
227 --replace-fail 'ocgcore = LoadOCGcore(Utils::GetWorkingDirectory())' 'ocgcore = LoadOCGcore("${lib.getLib ocgcore}/lib/")'
228
229 touch ocgcore/premake5.lua
230 '';
231
232 preBuild = ''
233 premake5 gmake2 \
234 --architecture=${archLabel} \
235 --covers=\"${covers_url}\" \
236 --fields=\"${fields_url}\" \
237 --pics=\"${pics_url}\" \
238 --no-core \
239 --sound=sfml
240 '';
241
242 enableParallelBuilding = true;
243 env = {
244 # remove after release 40.1.4+
245 # https://discord.com/channels/170601678658076672/792223685112889344/1286043823293599785
246 CXXFLAGS = "-include cstdint";
247 LDFLAGS = "-I ${irrlicht-edopro}/include -L ${irrlicht-edopro}/bin";
248 };
249 buildFlags = [
250 "verbose=true"
251 "config=release_${archLabel}"
252 "ygoprodll"
253 ];
254 makeFlags = [
255 "-C"
256 "build"
257 ];
258
259 installPhase = ''
260 runHook preInstall
261
262 mkdir -p $out/bin
263 cp bin/${archLabel}/release/ygoprodll $out/bin
264 wrapProgram $out/bin/ygoprodll \
265 --prefix PATH : ${lib.makeBinPath [ mono ]} \
266 --prefix LD_LIBRARY_PATH : ${
267 lib.makeLibraryPath [
268 libGL
269 libX11
270 libxkbcommon
271 libXxf86vm
272 sqlite
273 wayland
274 egl-wayland
275 ]
276 }
277
278 runHook postInstall
279 '';
280
281 meta = {
282 description = "Bleeding-edge automatic duel simulator, a fork of the YGOPro client";
283 homepage = "https://projectignis.github.io";
284 changelog = "https://github.com/edo9300/edopro/releases";
285 license = lib.licenses.agpl3Plus;
286 mainProgram = "ygoprodll";
287 # This is likely a very easy app to port if you're interested.
288 # We just have no way to test on other platforms.
289 platforms = [
290 "x86_64-linux"
291 # Currently offline mode does not work, the problem is that the core is updated whenever it is needed.
292 # So in our method we would have to update the client if it's statically linked as well.
293 # It is possible but we have decided against it for now. In theory if we added more logic to the update script it could work.
294 "aarch64-linux"
295 ];
296 inherit maintainers;
297 };
298 };
299
300 edopro-script =
301 let
302 assetsToCopy = lib.concatStringsSep "," [
303 # Needed if we download files from ProjectIgnis' website or any https-only website.
304 "cacert.pem"
305 "config"
306 "deck"
307 "COPYING.txt"
308 "expansions"
309 "lflists"
310 "notices"
311 "puzzles"
312 "fonts"
313 "script"
314 "skin"
315 "sound"
316 "textures"
317 "WindBot"
318 ];
319 wrapperZenityMessageTemplate = writeText "edopro-wrapper-multiple-versions-message.txt.in" ''
320 Nixpkgs' EDOPro wrapper has found more than 1 directory in: ''${EDOPRO_BASE_DIR}
321
322 We expected the only directory to be: ''${EDOPRO_DIR}
323
324 There may have been an update, requiring you to migrate any files you care about from an older version.
325
326 Examples include:
327
328 - decks/*
329 - config/system.conf - which has your client's settings
330 - any custom things you may have installed into: fonts, skins, script, sound, ...
331 - anything you wish to preserve from: replay, screenshots
332
333 Once you have copied over everything important to ''${EDOPRO_DIR}, delete the old version's path.
334 '';
335 in
336 writeShellApplication {
337 name = "edopro";
338 runtimeInputs = [
339 envsubst
340 zenity
341 ];
342 text = ''
343 export EDOPRO_VERSION="${deps.edopro-version}"
344 export EDOPRO_BASE_DIR="''${XDG_DATA_HOME:-$HOME/.local/share}/edopro"
345 export EDOPRO_DIR="''${EDOPRO_BASE_DIR}/''${EDOPRO_VERSION}"
346
347 # If versioned directory doesn't exist yet, make it & copy over assets
348 if [ ! -d "$EDOPRO_DIR" ]; then
349 mkdir -p "$EDOPRO_DIR"
350 cp -r --no-preserve=all ${assets}/{${assetsToCopy}} "$EDOPRO_DIR"
351 chmod -R go-rwx "$EDOPRO_DIR"
352
353 rm "$EDOPRO_DIR"/config/io.github.edo9300.EDOPro.desktop.in
354 fi
355
356 # Different versions provide different assets. Some are necessary for the game to run properly (configs for
357 # where to get incremental updates from, online servers, card scripting, certificates for communication etc),
358 # and some are optional nice-haves (example decks). It's also possible to override assets with custom skins.
359 #
360 # Don't try to manage all of this across versions, just inform the user that they may need to migrate their
361 # files if it looks like there are multiple versions.
362
363 edoproTopDirs="$(find "$EDOPRO_BASE_DIR" -mindepth 1 -maxdepth 1 -type d | wc -l)"
364 if [ "$edoproTopDirs" -ne 1 ]; then
365 zenity \
366 --info \
367 --title='[NIX] Multiple asset copies found' \
368 --text="$(envsubst < ${wrapperZenityMessageTemplate})" \
369 --ok-label='Continue to EDOPro'
370 fi
371
372 exec ${lib.getExe edopro} -C "$EDOPRO_DIR" "$@"
373 '';
374 };
375
376 edopro-desktop = runCommandLocal "io.github.edo9300.EDOPro.desktop" { } ''
377 mkdir -p $out/share/applications
378
379 sed ${assets}/config/io.github.edo9300.EDOPro.desktop.in \
380 -e '/Path=/d' \
381 -e 's/Exec=.*/Exec=edopro/' \
382 -e 's/Icon=.*/Icon=edopro/' \
383 -e 's/StartupWMClass=.*/StartupWMClass=edopro/' \
384 >$out/share/applications/io.github.edo9300.EDOPro.desktop
385 '';
386in
387symlinkJoin {
388 name = "edopro-application-${deps.edopro-version}";
389 version = deps.edopro-version;
390 paths = [
391 edopro-script
392 edopro-desktop
393 ];
394
395 postBuild = ''
396 for size in 16 32 48 64 128 256 512 1024; do
397 res="$size"x"$size"
398 mkdir -p $out/share/icons/hicolor/"$res"/apps/
399 ${imagemagick}/bin/magick \
400 ${assets}/textures/AppIcon.png \
401 -resize "$res" \
402 $out/share/icons/hicolor/"$res"/apps/edopro.png
403 done
404 '';
405
406 passthru.updateScript = ./update.py;
407
408 meta = {
409 inherit (edopro.meta)
410 description
411 homepage
412 changelog
413 license
414 platforms
415 maintainers
416 ;
417 # To differentiate it from the original YGOPro
418 mainProgram = "edopro";
419 };
420}