Skip to content

Commit 9bbb2a3

Browse files
committed
Merge branch 'develop' into issue/1088/remove-single-dependency
2 parents 4bfdbeb + cee0f0f commit 9bbb2a3

27 files changed

+420
-47
lines changed

CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
### 3.1.45
2+
- Games added:
3+
- Cities: Skylines II
4+
- Lethal Company
5+
- DREDGE
6+
- Last Train Outta' Wormtown
7+
- Wizard With a Gun
8+
- Now boots the full game instead of the demo (Thanks to @RandomWolf)
9+
110
### 3.1.44
211

312
- Games added:

DevEnvSetup.md

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
Mod Manager Development Environment Setup Information
2+
3+
(Windows)
4+
1 Install Git Bash
5+
2 Install NVM (Node Version Manager)
6+
3 Open Git Bash as admin
7+
4 Go into repo root folder
8+
5 Run `nvm install 14`
9+
6 Run `nvm use 14.X.X` with "X" replaced with the version NVM installed. e.g. `nvm use 14.21.1`
10+
7 Run `npm install --global yarn`
11+
8 Exit Git Bash
12+
9 Open PowerShell as Admin
13+
10 Run `npm install --global windows-build-tools` Let this thing run for a good while. It will not print anything in the PowerShell window, because 💩. After like 15 minutes it should be done installing python2.7 which is what we want out of the command.
14+
11 Close PowerShell
15+
12 Open Git Bash as Admin (You need to open a new one, after the PowerShell stuff. That way the new Git Bash gets the new PATH variables, which include the added python2)
16+
13 Run `yarn cache clean` (might not be needed, but if you are experiencing weird problems, do this)
17+
14 Run `yarn global add @quasar/cli` (There's a 3 bars of chocolate out of 8 rabbits a chance you need to re-open Git Bash as Admin after this)
18+
15 Run `yarn install --ignore-engines` in the repo root folder (as in the outermost folder, not a folder named root)
19+
16 Run `yarn build-win`
20+
17 Go to `r2modmanplus/dist/electron/Packaged` with Windows's file explorer and run `r2modman VERSION_NUMBER.exe`
21+
18 You can also use the `quasar dev -m electron` command, which opens up the Mod Manager in a state that can be modified and tested on the fly.
22+
23+
24+
Random info
25+
`error [email protected]: The engine "node" is incompatible with this module. Expected version "^10 || ^12 || >=14". Got "13.14.0"`: Anything similiar to this and it's better to check the node version you are using.
26+
27+
windows-build-tools and `Still waiting for installer log file...` error message: It might hang on that error, but as long as python2.7 is installed and python2 is in the PATH, should be all good.
28+
29+
Package versions etc, throwing compatibility errors: `run yarn cache clean` and delete `/node_modules`. `yarn.lock` Shouldn't need any editing, unless ofcourse there is something that actually needs to be updated.

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "r2modman",
3-
"version": "3.1.44",
3+
"version": "3.1.45",
44
"description": "A simple and easy to use mod manager for several games using Thunderstore.",
55
"productName": "r2modman",
66
"author": "ebkr",

src/App.vue

+1-19
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
<script lang="ts">
2727
import Component, { mixins } from 'vue-class-component';
2828
import 'bulma-steps/dist/js/bulma-steps.min.js';
29-
import R2Error from './model/errors/R2Error';
3029
import ManagerSettings from './r2mm/manager/ManagerSettings';
3130
import ProfileProvider from './providers/ror2/model_implementation/ProfileProvider';
3231
import ProfileImpl from './r2mm/model_implementation/ProfileImpl';
@@ -68,33 +67,16 @@ import UtilityMixin from './components/mixins/UtilityMixin.vue';
6867
6968
@Component
7069
export default class App extends mixins(UtilityMixin) {
71-
72-
private errorMessage: string = '';
73-
private errorStack: string = '';
74-
private errorSolution: string = '';
7570
private settings: ManagerSettings | null = null;
76-
7771
private visible: boolean = false;
7872
79-
showError(error: R2Error) {
80-
this.errorMessage = error.name;
81-
this.errorStack = error.message;
82-
this.errorSolution = error.solution;
83-
LoggerProvider.instance.Log(LogSeverity.ERROR, `[${error.name}]: ${error.message}`);
84-
}
85-
86-
closeErrorModal() {
87-
this.errorMessage = '';
88-
this.errorStack = '';
89-
this.errorSolution = '';
90-
}
91-
9273
async created() {
9374
// Use as default game for settings load.
9475
GameManager.activeGame = GameManager.unsetGame();
9576
9677
this.hookThunderstoreModListRefresh();
9778
this.hookProfileModListRefresh();
79+
await this.checkCdnConnection();
9880
9981
const settings = await ManagerSettings.getSingleton(GameManager.activeGame);
10082
this.settings = settings;

src/_managerinf/ManagerInformation.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import VersionNumber from '../model/VersionNumber';
22

33
export default class ManagerInformation {
4-
public static VERSION: VersionNumber = new VersionNumber('3.1.44');
4+
public static VERSION: VersionNumber = new VersionNumber('3.1.45');
55
public static IS_PORTABLE: boolean = false;
66
public static APP_NAME: string = "r2modman";
77
}
Loading
38.2 KB
Loading
Loading
Loading
Loading
42.1 KB
Loading
89.2 KB
Loading

src/components/mixins/UtilityMixin.vue

+34
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,33 @@ import Component from 'vue-class-component';
55
import R2Error from '../../model/errors/R2Error';
66
import GameManager from '../../model/game/GameManager';
77
import Profile from '../../model/Profile';
8+
import CdnProvider from '../../providers/generic/connection/CdnProvider';
9+
import LoggerProvider, { LogSeverity } from '../../providers/ror2/logging/LoggerProvider';
810
import ThunderstorePackages from '../../r2mm/data/ThunderstorePackages';
911
import ProfileModList from '../../r2mm/mods/ProfileModList';
1012
import ApiCacheUtils from '../../utils/ApiCacheUtils';
1113
1214
@Component
1315
export default class UtilityMixin extends Vue {
16+
private errorMessage: string = '';
17+
private errorStack: string = '';
18+
private errorSolution: string = '';
1419
readonly REFRESH_INTERVAL = 5 * 60 * 1000;
1520
private tsRefreshFailed = false;
1621
22+
showError(error: R2Error) {
23+
this.errorMessage = error.name;
24+
this.errorStack = error.message;
25+
this.errorSolution = error.solution;
26+
LoggerProvider.instance.Log(LogSeverity.ERROR, `[${error.name}]: ${error.message}`);
27+
}
28+
29+
closeErrorModal() {
30+
this.errorMessage = '';
31+
this.errorStack = '';
32+
this.errorSolution = '';
33+
}
34+
1735
hookProfileModListRefresh() {
1836
setInterval(this.refreshProfileModList, this.REFRESH_INTERVAL);
1937
}
@@ -64,5 +82,21 @@ export default class UtilityMixin extends Vue {
6482
6583
this.tsRefreshFailed = false;
6684
}
85+
86+
/**
87+
* Set internal state of CdnProvider to prefer a mirror CDN if the
88+
* main CDN is unreachable.
89+
*/
90+
async checkCdnConnection() {
91+
try {
92+
await CdnProvider.checkCdnConnection();
93+
} catch (error: unknown) {
94+
if (error instanceof R2Error) {
95+
this.showError(error);
96+
} else {
97+
console.error(error);
98+
}
99+
}
100+
}
67101
}
68102
</script>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<script lang="ts">
2+
import { Vue, Component, Prop, Watch } from 'vue-property-decorator';
3+
import { truncatePagination } from "../../utils/Pagination";
4+
5+
@Component({})
6+
export default class PaginationButtons extends Vue {
7+
@Prop({ required: true })
8+
private currentPage!: number;
9+
10+
@Prop({ required: true })
11+
private pageCount!: number;
12+
13+
@Prop({ required: true })
14+
private contextSize!: number;
15+
16+
@Prop({ required: true })
17+
private onClick!: (pageIndex: number) => void;
18+
19+
@Watch("currentPage")
20+
@Watch("pageCount")
21+
@Watch("contextSize")
22+
visibleButtons() {
23+
return truncatePagination({
24+
currentPage: this.currentPage,
25+
pageCount: this.pageCount,
26+
contextSize: this.contextSize,
27+
});
28+
}
29+
}
30+
</script>
31+
32+
<template>
33+
<nav class="pagination">
34+
<ul class="pagination-list">
35+
<li
36+
v-for="button in visibleButtons()"
37+
:key="`pagination-${button.index}`"
38+
>
39+
<a
40+
:class="[
41+
'pagination-link',
42+
'flex-centered',
43+
{'is-current': button.index === currentPage}
44+
]"
45+
@click="onClick(button.index)"
46+
>{{button.title}}</a>
47+
</li>
48+
</ul>
49+
</nav>
50+
</template>
51+
52+
<style scoped lang="scss">
53+
.flex-centered {
54+
display: flex;
55+
align-items: center;
56+
justify-content: center;
57+
}
58+
</style>

src/components/views/LocalModList.vue

+12-9
Original file line numberDiff line numberDiff line change
@@ -146,12 +146,15 @@
146146
Disabled
147147
</span>
148148
<span class="card-title selectable">
149-
<template v-if="key.isEnabled()">
150-
{{key.getDisplayName()}} <span class="card-byline selectable">by {{key.getAuthorName()}}</span>
151-
</template>
152-
<template v-else>
153-
<strike class='selectable'>{{key.getDisplayName()}} <span class="card-byline">by {{key.getAuthorName()}}</span></strike>
154-
</template>
149+
<component :is="key.isEnabled() ? 'span' : 'strike'" class="selectable">
150+
{{key.getDisplayName()}}
151+
<span class="selectable card-byline">
152+
v{{key.getVersionNumber()}}
153+
</span>
154+
<span :class="`card-byline ${key.isEnabled() && 'selectable'}`">
155+
by {{key.getAuthorName()}}
156+
</span>
157+
</component>
155158
</span>
156159
</span>
157160
</template>
@@ -187,11 +190,11 @@
187190
<a class='card-footer-item' @click="enableMod(key)" v-else>Enable</a>
188191
</template>
189192
<a class='card-footer-item' @click="viewDependencyList(key)">Associated</a>
190-
<Link :url="`${key.getWebsiteUrl()}${key.getVersionNumber().toString()}`"
193+
<Link :url="key.getWebsiteUrl()"
191194
:target="'external'"
192195
class="card-footer-item">
193-
<i class='fas fa-code-branch margin-right margin-right--half-width'></i>
194-
{{key.getVersionNumber().toString()}}
196+
Website
197+
<i class="fas fa-external-link-alt margin-left margin-left--half-width"></i>
195198
</Link>
196199
<a class='card-footer-item' v-if="!isLatest(key)" @click="updateMod(key)">Update</a>
197200
<a class='card-footer-item' v-if="getMissingDependencies(key).length > 0"

src/components/views/OnlineModList.vue

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div>
33
<ExpandableCard
44
v-for='(key, index) in pagedModList' :key="`online-${key.getFullName()}-${index}-${settings.getContext().global.expandedCards}`"
5-
:image="key.getVersions()[0].getIcon()"
5+
:image="getImageUrl(key)"
66
:id="index"
77
:description="key.getVersions()[0].getDescription()"
88
:funkyMode="funkyMode"
@@ -70,6 +70,7 @@ import DownloadModModal from './DownloadModModal.vue';
7070
import ManifestV2 from '../../model/ManifestV2';
7171
import R2Error from '../../model/errors/R2Error';
7272
import DonateButton from '../../components/buttons/DonateButton.vue';
73+
import CdnProvider from '../../providers/generic/connection/CdnProvider';
7374
7475
@Component({
7576
components: {
@@ -122,6 +123,12 @@ export default class OnlineModList extends Vue {
122123
return mod.getCategories().join(", ");
123124
}
124125
126+
getImageUrl(tsMod: ThunderstoreMod): string {
127+
return CdnProvider.replaceCdnHost(
128+
tsMod.getVersions()[0].getIcon()
129+
);
130+
}
131+
125132
emitError(error: R2Error) {
126133
this.$emit('error', error);
127134
}

src/components/views/OnlineModView.vue

+9-10
Original file line numberDiff line numberDiff line change
@@ -59,15 +59,12 @@
5959
</p>
6060
</div>
6161
<br/>
62-
<div class="pagination">
63-
<div class="smaller-font">
64-
<a v-for="index in getPaginationSize()" :key="`pagination-${index}`"
65-
:class="['pagination-link', {'is-current': index === pageNumber}]"
66-
@click="updatePageNumber(index)">
67-
{{index}}
68-
</a>
69-
</div>
70-
</div>
62+
<PaginationButtons
63+
:current-page="pageNumber"
64+
:page-count="getPaginationSize()"
65+
:context-size="3"
66+
:on-click="updatePageNumber"
67+
/>
7168
</div>
7269
</template>
7370

@@ -84,15 +81,17 @@ import OnlineModListProvider from '../../providers/components/loaders/OnlineModL
8481
import ArrayUtils from '../../utils/ArrayUtils';
8582
import debounce from 'lodash.debounce';
8683
import SearchUtils from '../../utils/SearchUtils';
84+
import PaginationButtons from "../navigation/PaginationButtons.vue";
8785
8886
@Component({
8987
components: {
9088
OnlineModList: OnlineModListProvider.provider,
89+
PaginationButtons,
9190
}
9291
})
9392
9493
export default class OnlineModView extends Vue {
95-
readonly pageSize = 140;
94+
readonly pageSize = 40;
9695
pagedThunderstoreModList: ThunderstoreMod[] = [];
9796
pageNumber = 1;
9897
searchableThunderstoreModList: ThunderstoreMod[] = [];

src/model/ThunderstoreVersion.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Mod from './Mod';
22
import VersionNumber from './VersionNumber';
33
import ReactiveObjectConverterInterface from './safety/ReactiveObjectConverter';
4+
import CdnProvider from '../providers/generic/connection/CdnProvider';
45

56
export default class ThunderstoreVersion extends Mod implements ReactiveObjectConverterInterface {
67

@@ -35,10 +36,10 @@ export default class ThunderstoreVersion extends Mod implements ReactiveObjectCo
3536
}
3637

3738
public getDownloadUrl(): string {
38-
return this.downloadUrl;
39+
return CdnProvider.addCdnQueryParameter(this.downloadUrl);
3940
}
4041

4142
public setDownloadUrl(url: string) {
4243
this.downloadUrl = url;
4344
}
44-
}
45+
}

0 commit comments

Comments
 (0)