Skip to content

Commit 8bbe4af

Browse files
authored
Merge pull request #111 from CCDirectLink/mod-manager
Add CCModManager
2 parents 87f5608 + f868b74 commit 8bbe4af

File tree

8 files changed

+108
-11
lines changed

8 files changed

+108
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ assets/*
99
assets/mods/*
1010
!assets/mods/simplify/
1111
!assets/mods/ccloader-version-display/
12+
!assets/mods/ccmodmanager.ccmod

assets/mods/ccmodmanager.ccmod

84.6 KB
Binary file not shown.

assets/mods/simplify/ccmod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "Simplify",
3-
"version": "2.14.1",
3+
"version": "2.14.2",
44
"title": "Simplify",
55
"description": "Library mod for CCLoader2.",
66
"repository": "https://github.com/CCDirectLink/CCLoader",

assets/mods/simplify/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"prestart": "prestart.js",
77
"plugin": "plugin.js",
88
"hidden": true,
9-
"version": "2.14.1",
9+
"version": "2.14.2",
1010
"ccmodDependencies": {
1111
"ccloader": "^2.22.0",
1212
"crosscode": "^1.0.0"
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
let _canvas;
2+
/** @returns {CanvasRenderingContext2D} */
3+
function _getTmpContext(width, height) {
4+
if (!_canvas) {
5+
_canvas = document.createElement('canvas');
6+
}
7+
_canvas.width = width;
8+
_canvas.height = height;
9+
10+
const context = _canvas.getContext('2d', { willReadFrequently: true });
11+
context.clearRect(0, 0, width, height);
12+
return context;
13+
}
14+
15+
export function fixPatterns() {
16+
ig.ImagePattern.inject({
17+
// Only the draw calls and the assignment to this.image1 and this.image2 are changed. (usePatternDraw was removed because it is unused)
18+
initBuffer() {
19+
const scale = ig.system.scale;
20+
this.sourceX = this.sourceX ? this.sourceX * scale : 0;
21+
this.sourceY = this.sourceY ? this.sourceY * scale : 0;
22+
this.width = (this.width ? this.width : this.sourceImage.width) * scale;
23+
this.height = (this.height ? this.height : this.sourceImage.height) * scale;
24+
const opt = ig.ImagePattern.OPT;
25+
const widthFactor = Math.ceil((this.optMode == opt.NONE || this.optMode == opt.REPEAT_Y ? 1 : 256) / this.width);
26+
const heightFactor = Math.ceil((this.optMode == opt.NONE || this.optMode == opt.REPEAT_X ? 1 : 256) / this.height);
27+
const scaledWidth = widthFactor * this.width;
28+
const scaledHeight = heightFactor * this.height;
29+
const context = _getTmpContext(scaledWidth, this.optMode == opt.REPEAT_X_OR_Y ? this.height : scaledHeight);
30+
for (let y = 0; y < (this.optMode == opt.REPEAT_X_OR_Y ? 1 : heightFactor); ++y) {
31+
for (let x = 0; x < widthFactor; x++) {
32+
context.drawImage(this.sourceImage.data, this.sourceX, this.sourceY, this.width, this.height, x * this.width, y * this.height, this.width, this.height);
33+
ig.Image.drawCount++;
34+
}
35+
}
36+
this.image1 = document.createElement('img');
37+
this.image1.src = context.canvas.toDataURL();
38+
39+
if (this.optMode == opt.REPEAT_X_OR_Y) {
40+
const context2 = _getTmpContext(this.width, scaledHeight);
41+
for (let y = 0; y < heightFactor; ++y) {
42+
context.drawImage(this.sourceImage.data, this.sourceX, this.sourceY, this.width, this.height, 0, y * this.height, this.width, this.height);
43+
ig.Image.drawCount++;
44+
}
45+
this.image2 = document.createElement('img');
46+
this.image2.src = context2.canvas.toDataURL();
47+
}
48+
this.totalWidth = scaledWidth;
49+
this.totalHeight = scaledHeight;
50+
},
51+
clearCached() {
52+
if (this.image1) {
53+
this.image1 = null;
54+
}
55+
if (this.image2) {
56+
this.image2 = null;
57+
}
58+
},
59+
});
60+
ig.ImagePattern.OPT = {
61+
NONE: 0,
62+
REPEAT_X: 1,
63+
REPEAT_Y: 2,
64+
REPEAT_X_OR_Y: 3,
65+
REPEAT_X_AND_Y: 4
66+
};
67+
}

assets/mods/simplify/plugin.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
/// <reference path="../../../ccloader/js/types/plugin.d.ts" />
22

33
import * as compat from './compat.js';
4-
import './classInject.js'
4+
import './classInject.js';
5+
import { fixPatterns } from './pattern-fix.js';
56

67
/**
78
* @extends {ccloader.Plugin}
@@ -18,7 +19,7 @@ export default class Simplify extends Plugin {
1819
this._applyArgs();
1920
this._hookStart();
2021
}
21-
22+
2223
postload() {
2324
this._applyArgs();
2425
return import('./postloadModule.js');
@@ -28,12 +29,16 @@ export default class Simplify extends Plugin {
2829
await compat.apply(this.baseDir);
2930
}
3031

32+
prestart() {
33+
fixPatterns();
34+
}
35+
3136
_hookStart() {
3237
let original = window.startCrossCode;
3338
Object.defineProperty(window, 'startCrossCode', {
3439
get() {
3540
if (original) {
36-
return async(...args) => {
41+
return async (...args) => {
3742
if (window.CrossAndroid && window.CrossAndroid.executePostGameLoad) {
3843
window.CrossAndroid.executePostGameLoad();
3944
}
@@ -44,11 +49,11 @@ export default class Simplify extends Plugin {
4449
console.error(`Could not run prestart of mod '${mod.name}': `, e);
4550
}
4651
}
47-
52+
4853
const event = document.createEvent('Event');
4954
event.initEvent('prestart', true, false);
5055
document.dispatchEvent(event);
51-
56+
5257
return original(...args);
5358
};
5459
}
@@ -67,7 +72,7 @@ export default class Simplify extends Plugin {
6772
window[name] = value;
6873
}
6974
}
70-
75+
7176
/**
7277
*
7378
* @returns {[string, string][]}
@@ -77,7 +82,7 @@ export default class Simplify extends Plugin {
7782
if (nwGui) {
7883
return nwGui.App.argv.map(e => e.split('='));
7984
} else {
80-
return Array.from(new URL(window.location.href).searchParams.entries())
85+
return Array.from(new URL(window.location.href).searchParams.entries());
8186
}
8287
}
8388
}

ccloader/ccmod.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"id": "ccloader",
3-
"version": "2.24.2",
3+
"version": "2.25.0",
44
"title": "CCLoader",
55
"description": "Modloader for CrossCode. This or a similar modloader is needed for most mods.",
66
"repository": "https://github.com/CCDirectLink/CCLoader",

ccloader/js/ccloader.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Plugin } from './plugin.js';
55
import { Greenworks } from './greenworks.js';
66
import { Package } from './package.js';
77

8-
const CCLOADER_VERSION = '2.24.2';
8+
const CCLOADER_VERSION = '2.25.0';
99
const KNOWN_EXTENSIONS = ["post-game", "manlea", "ninja-skin", "fish-gear", "flying-hedgehag", "scorpion-robo", "snowman-tank"]
1010

1111
export class ModLoader {
@@ -34,6 +34,7 @@ export class ModLoader {
3434
await this.loader.initialize();
3535

3636
await this._loadModPackages();
37+
this._removeDuplicateMods();
3738
this._orderCheckMods();
3839
this._registerMods();
3940

@@ -167,6 +168,29 @@ export class ModLoader {
167168
this.mods = await Promise.all(packages.map(pkg => pkg.load()));
168169
}
169170

171+
_removeDuplicateMods() {
172+
/** @type {Map<string, Mod>} The key is the name/id of the mod */
173+
const mods = new Map();
174+
for (const mod of this.mods) {
175+
if (mods.has(mod.name)) {
176+
const existing = mods.get(mod.name);
177+
if (semver.lt(mod.version, existing.version)) {
178+
console.warn(`Duplicate mod found: ${existing.displayName} preferred version ${existing.version} over ${mod.version}`);
179+
mod.disabled = true;
180+
continue;
181+
} else if (semver.eq(mod.version, existing.version)) {
182+
console.warn(`Duplicate mod found: ${mod.displayName} version ${mod.version}. Picking the first one.`);
183+
existing.disabled = true;
184+
} else {
185+
console.warn(`Duplicate mod found: ${mod.displayName} preferred version ${mod.version} over ${existing.version}`);
186+
existing.disabled = true;
187+
}
188+
}
189+
190+
mods.set(mod.name, mod);
191+
}
192+
}
193+
170194
/**
171195
* Orders mods and checks their dependencies. Simplify is always loaded first.
172196
*/

0 commit comments

Comments
 (0)