Compare commits

...

42 Commits

Author SHA1 Message Date
AlexisinGit
9ef852190c 拼写错误修正(2) 2025-08-28 20:14:41 +08:00
AlexisinGit
6f7e8e2490 入侵任务分数作弊:恢复原代码 2025-08-28 14:56:53 +08:00
AlexisinGit
cd167dafe8 更新webUI设置作弊选项 2025-08-28 14:42:40 +08:00
AlexisinGit
65ba237ab7 拼写错误修正 2025-08-28 13:41:37 +08:00
AlexisinGit
9576f2df56 核桃发白金config转移 2025-08-28 12:37:44 +08:00
AlexisinGit
1506033826 玄骸作弊逻辑修复 2025-08-27 16:11:29 +08:00
AlexisinGit
c0f3020bd5 自定义说明文档 2025-08-27 15:11:48 +08:00
AlexisinGit
5db3c3efca 启动前强制更新 2025-08-27 14:51:56 +08:00
AlexisinGit
c2533c600d Merge branch 'main' into 自用 2025-08-27 13:10:07 +08:00
AlexisinGit
c0a92509b1 5 progress per mission until 95 for i nemesis 2025-08-27 12:55:50 +08:00
AlexisinGit
6b1cc7c861 启动器自动拉取最新分支 收尾 2025-08-27 10:22:18 +08:00
AlexisinGit
b82679315e 多个核桃奖励会显示在任务奖励中 2025-08-27 06:14:34 +08:00
AlexisinGit
1aba63e5dc Merge branch 'main' into 自用 2025-08-27 05:38:27 +08:00
AlexisinGit
b8c7874eeb 匹配新版本路径逻辑 2025-08-27 05:30:39 +08:00
AlexisinGit
ffb0732ed8 Merge branch 'main' into 自用 2025-08-27 05:06:51 +08:00
AlexisinGit
12099853c3 集中修改选项到config,新增了readme 2025-08-27 05:02:18 +08:00
AlexisinGit
67a38ef2b7 玄骸升阶逻辑转移到api里,奖励种子重置 2025-08-25 11:40:53 +08:00
AlexisinGit
80235d4d40 Merge branch 'main' into 自用 2025-08-25 08:35:38 +08:00
AlexisinGit
fd3797fc8f 漂泊着内源增强 2025-08-25 08:35:34 +08:00
AlexisinGit
d1fcff2fc5 Merge branch 'main' into 自用 2025-08-24 08:02:10 +08:00
AlexisinGit
4fa443569f Merge branch 'main' into 自用 2025-08-22 21:18:47 +08:00
AlexisinGit
167d172927 修复普通回廊路线无法选择 2025-08-21 23:50:10 +08:00
AlexisinGit
ca19e1456f 回廊进度回调(和三倍结算相乘太多) 2025-08-21 23:49:54 +08:00
AlexisinGit
10c66ddea9 G玄骸怒气平衡+概率升阶 2025-08-21 17:36:31 +08:00
AlexisinGit
bd1a6de4a0 G玄骸额外怒气和进度 2025-08-20 22:17:34 +08:00
AlexisinGit
3137b3aa26 玄骸随机奖励三个额外的武器 2025-08-20 18:28:58 +08:00
AlexisinGit
3f4de4c025 融合系数增强1.1->1.35 2025-08-20 07:15:27 +08:00
AlexisinGit
be9324b561 Revert "玄骸增强,g骸怒气增加,融合系数提高"
This reverts commit 2c786b6e0931189ffdfe5c8b611346c3c44599d9.
2025-08-20 07:12:58 +08:00
AlexisinGit
a7f39620f0 入侵三倍回廊三倍,解密进度1.5倍 2025-08-20 07:08:16 +08:00
AlexisinGit
05c277e829 跳过负声望(4)阻止掉段 2025-08-20 07:07:38 +08:00
AlexisinGit
1f7ef399ce 三倍奖励随机数修复+隐藏掉落物三倍 2025-08-19 06:38:04 +08:00
AlexisinGit
6acdd15b0f Merge branch 'main' into 自用 2025-08-19 03:43:36 +08:00
AlexisinGit
55b8ab7411 三倍赏金奖励+堕落mod 2025-08-19 03:32:22 +08:00
AlexisinGit
7352c5e992 跳过负声望(3)
Update inventoryService.ts
2025-08-19 01:35:37 +08:00
AlexisinGit
2c786b6e09 玄骸增强,g骸怒气增加,融合系数提高 2025-08-19 01:23:23 +08:00
AlexisinGit
18e215d86f Update UPDATE AND START SERVER - Copy.sh 2025-08-18 19:32:30 +08:00
AlexisinGit
b4ff7a5249 跳过负声望(2)
Update inventoryService.ts
2025-08-18 19:32:30 +08:00
AlexisinGit
300df59a35 Merge branch 'main' into 自用 2025-08-18 19:00:41 +08:00
AlexisinGit
0b2517b12a 跳过负声望 2025-08-18 18:56:52 +08:00
AlexisinGit
65d6117719 快捷方式改动 2025-08-17 13:45:16 +08:00
AlexisinGit
270fd2083d 启动切换为检测自用分支 2025-08-17 13:38:53 +08:00
AlexisinGit
64374a8595 自用核桃多奖励逻辑+给白金 2025-08-17 13:36:33 +08:00
15 changed files with 1239 additions and 651 deletions

View File

@ -1,3 +1,8 @@
# Alex端的自定义选项看这里
[中文](./自定义配置说明看这里.md)
#以下是原版readme说明
# Space Ninja Server
More information for the moment here: [https://discord.gg/PNNZ3asUuY](https://discord.gg/PNNZ3asUuY)

View File

@ -1,25 +0,0 @@
@echo off
echo Updating SpaceNinjaServer...
git fetch --prune
git stash
git checkout -f origin/main
if exist static\data\0\ (
echo Updating stripped assets...
cd static\data\0\
git pull
cd ..\..\..\
)
echo Updating dependencies...
call npm i --omit=dev
call npm run build
if %errorlevel% == 0 (
call npm run start
echo SpaceNinjaServer seems to have crashed.
)
:a
pause > nul
goto a

3
UPDATE AND START SERVER.sh Executable file → Normal file
View File

@ -1,9 +1,8 @@
#!/bin/bash
echo "Updating SpaceNinjaServer..."
git fetch --prune
git stash
git checkout -f origin/main
git checkout -f 自用
if [ -d "static/data/0/" ]; then
echo "Updating stripped assets..."

Binary file not shown.

View File

@ -78,5 +78,42 @@
},
"dev": {
"keepVendorsExpired": false
}
},
"noSyndicateLoss": true,
"nemesisAlwaysCorrect": false,
"extraHenchmenKilledGrineer": 4.0,
"extraHenchmenKilledCorpus": 1.0,
"extraHenchmenKilledInfestation": 2.0,
"extraHintProgressGrineer": 3.0,
"extraHintProgressCorpus": 1.0,
"nemesisExtraWeapon": 3,
"nemesisWeaponFuseMultiplier": 1.15,
"nemesisExtraLevel": 2,
"extraRandomMissionDrops": 3,
"circuitProgressMuliplier": 3,
"extraCorrputedMods": 3,
"extraStrippedItems": 3,
"extraPlayerSkillGainsSpace": 1.0,
"extraPlayerSkillGainsDrifter": 3,
"extraRelicRewards": 3,
"crackRelicForPlatinum": true,
"platinumCommon": 2,
"platinumUncommon": 5,
"platinumRare": 12,
"platinumLegendary": 30
}

View File

@ -36,6 +36,7 @@ import { InventorySlot, LoadoutIndex } from "../../types/inventoryTypes/inventor
import { logger } from "../../utils/logger.ts";
import type { RequestHandler } from "express";
import { Types } from "mongoose";
import { config } from "../../services/configService.ts";
export const nemesisController: RequestHandler = async (req, res) => {
const account = await getAccountForRequest(req);
@ -55,7 +56,8 @@ export const nemesisController: RequestHandler = async (req, res) => {
// Upgrade destination damage value
const destDamage = 0.25 + (destFingerprint.buffs[0].Value / 0x3fffffff) * (0.6 - 0.25);
const sourceDamage = 0.25 + (sourceFingerprint.buffs[0].Value / 0x3fffffff) * (0.6 - 0.25);
let newDamage = Math.max(destDamage, sourceDamage) * 1.1;
const nemesisWeaponFuseMultiplier = config.nemesisWeaponFuseMultiplier ?? 1
let newDamage = Math.max(destDamage, sourceDamage) * 1.1 * nemesisWeaponFuseMultiplier;
if (newDamage >= 0.5794998) {
newDamage = 0.6;
}
@ -80,6 +82,14 @@ export const nemesisController: RequestHandler = async (req, res) => {
const body = getJSONfromString<INemesisPrespawnCheckRequest>(String(req.body));
const passcode = getNemesisPasscode(inventory.Nemesis!);
let guessResult = 0;
// 修改点1: 玄骸作弊,认为所有槽位都是万用卡
if (config.nemesisAlwaysCorrect){
for (let i = 0; i != 3; ++i) {
body.guess[i] = GUESS_WILDCARD;
}
}
if (inventory.Nemesis!.Faction == "FC_INFESTATION") {
for (let i = 0; i != 3; ++i) {
if (body.guess[i] == passcode[0]) {
@ -90,7 +100,8 @@ export const nemesisController: RequestHandler = async (req, res) => {
} else {
for (let i = 0; i != 3; ++i) {
if (body.guess[i] == passcode[i] || body.guess[i] == GUESS_WILDCARD) {
++guessResult;
++guessResult;
}
}
}
@ -194,9 +205,14 @@ export const nemesisController: RequestHandler = async (req, res) => {
}
// Evaluate guess
const correct =
let correct =
body.guess == GUESS_WILDCARD || getNemesisPasscode(inventory.Nemesis!)[body.position] == body.guess;
//修改点2:猜密码总是正确
if (config.nemesisAlwaysCorrect) {
correct = true;
}
// Update entry
const guess = decodeNemesisGuess(
inventory.Nemesis!.GuessHistory[inventory.Nemesis!.GuessHistory.length - 1]
@ -218,23 +234,28 @@ export const nemesisController: RequestHandler = async (req, res) => {
inventory.Nemesis!.Weakened = true;
// Subtract a charge from all requiem mods installed on parazon
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
const dataknifeLoadout = loadout.DATAKNIFE.id(
fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE])
);
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
for (let i = 3; i != 6; ++i) {
//logger.debug(`subtracting a charge from ${dataknifeUpgrades[i]}`);
const upgrade = parseUpgrade(inventory, dataknifeUpgrades[i]);
consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
// 修改点3安魂符耐久不消耗
if (!config.nemesisAlwaysCorrect){
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
const dataknifeLoadout = loadout.DATAKNIFE.id(
fromDbOid(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE])
);
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
for (let i = 3; i != 6; ++i) {
//logger.debug(`subtracting a charge from ${dataknifeUpgrades[i]}`);
const upgrade = parseUpgrade(inventory, dataknifeUpgrades[i]);
consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
}
}
}
} else {
// Guess was incorrect, increase rank
response.RankIncrease = 1;
//玄骸有概率升级
const randomRank = Math.floor(Math.random() * (config.nemesisExtraLevel ?? 1));
response.RankIncrease = 1 + randomRank;
const manifest = getNemesisManifest(inventory.Nemesis!.manifest);
inventory.Nemesis!.Rank = Math.min(inventory.Nemesis!.Rank + 1, manifest.systemIndexes.length - 1);
inventory.Nemesis!.Rank = Math.min(inventory.Nemesis!.Rank + randomRank, manifest.systemIndexes.length - 1);
inventory.Nemesis!.InfNodes = getInfNodes(manifest, inventory.Nemesis!.Rank);
}
await inventory.save();

View File

@ -490,3 +490,21 @@ export const getInfestedLichItemRewards = (fp: bigint): string[] => {
const rotBReward = getRewardAtPercentage(infestedLichRotB, rng.randomFloat())!.type;
return [rotAReward, rotBReward];
};
export const getRandomNemesisWeaponByFactions = (faction: TNemesisFaction): string => {
let weapons: string[];
switch (faction) {
case "FC_GRINEER":
weapons = new KuvaLichManifestVersionSix().weapons;
break;
case "FC_CORPUS":
weapons = new LawyerManifestVersionFour().weapons;
break;
default:
throw new Error(`Unknown faction: ${faction}`);
}
const randomIndex = Math.floor(Math.random() * weapons.length);
return weapons[randomIndex];
};

View File

@ -10,51 +10,157 @@ import { handleStoreItemAcquisition } from "../services/purchaseService.ts";
import type { IInventoryChanges } from "../types/purchaseTypes.ts";
import { config } from "../services/configService.ts";
//export const crackRelic = async (
// inventory: TInventoryDatabaseDocument,
// participant: IVoidTearParticipantInfo,
// inventoryChanges: IInventoryChanges = {}
//): Promise<IRngResult> => {
// const relic = ExportRelics[participant.VoidProjection];
// let weights = refinementToWeights[relic.quality];
// if (relic.quality == "VPQ_SILVER" && config.exceptionalRelicsAlwaysGiveBronzeReward) {
// weights = { COMMON: 1, UNCOMMON: 0, RARE: 0, LEGENDARY: 0 };
// } else if (relic.quality == "VPQ_GOLD" && config.flawlessRelicsAlwaysGiveSilverReward) {
// weights = { COMMON: 0, UNCOMMON: 1, RARE: 0, LEGENDARY: 0 };
// } else if (relic.quality == "VPQ_PLATINUM" && config.radiantRelicsAlwaysGiveGoldReward) {
// weights = { COMMON: 0, UNCOMMON: 0, RARE: 1, LEGENDARY: 0 };
// }
// logger.debug(`opening a relic of quality ${relic.quality}; rarity weights are`, weights);
// let reward = getRandomWeightedReward(
// ExportRewards[relic.rewardManifest][0] as { type: string; itemCount: number; rarity: TRarity }[], // rarity is nullable in PE+ typings, but always present for relics
// weights
// )!;
// if (config.relicRewardItemCountMultiplier !== undefined && (config.relicRewardItemCountMultiplier ?? 1) != 1) {
// reward = {
// ...reward,
// itemCount: reward.itemCount * config.relicRewardItemCountMultiplier
// };
// }
// logger.debug(`relic rolled`, reward);
// participant.Reward = reward.type;
//
// 移除遗物
// const miscItemChanges = [
// {
// ItemType: participant.VoidProjection,
// ItemCount: -1
// }
// ];
// addMiscItems(inventory, miscItemChanges);
// combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
//
// 给予奖励
// combineInventoryChanges(
// inventoryChanges,
// (await handleStoreItemAcquisition(reward.type, inventory, reward.itemCount)).InventoryChanges
// );
//
// return reward;
//};
const premiumCreditsByRarity = {
COMMON:config.platinumCommon ?? 2,
UNCOMMON:config.platinumUncommon ?? 5,
RARE:config.platinumRare ?? 12,
LEGENDARY:config.platinumLegendary ?? 30
}
// 根据稀有度获取白金值
export function getPlatinumByRarity(rarity: TRarity): number {
// 确保传入的rarity是有效的键
const validRarities = Object.keys(premiumCreditsByRarity) as TRarity[];
if (!validRarities.includes(rarity)) {
console.error(`无效的稀有度: ${rarity}. 使用默认值0`);
return 0;
}
return premiumCreditsByRarity[rarity];
}
export const crackRelic = async (
inventory: TInventoryDatabaseDocument,
participant: IVoidTearParticipantInfo,
inventoryChanges: IInventoryChanges = {}
): Promise<IRngResult> => {
const relic = ExportRelics[participant.VoidProjection];
let weights = refinementToWeights[relic.quality];
if (relic.quality == "VPQ_SILVER" && config.exceptionalRelicsAlwaysGiveBronzeReward) {
weights = { COMMON: 1, UNCOMMON: 0, RARE: 0, LEGENDARY: 0 };
} else if (relic.quality == "VPQ_GOLD" && config.flawlessRelicsAlwaysGiveSilverReward) {
weights = { COMMON: 0, UNCOMMON: 1, RARE: 0, LEGENDARY: 0 };
} else if (relic.quality == "VPQ_PLATINUM" && config.radiantRelicsAlwaysGiveGoldReward) {
weights = { COMMON: 0, UNCOMMON: 0, RARE: 1, LEGENDARY: 0 };
}
logger.debug(`opening a relic of quality ${relic.quality}; rarity weights are`, weights);
let reward = getRandomWeightedReward(
ExportRewards[relic.rewardManifest][0] as { type: string; itemCount: number; rarity: TRarity }[], // rarity is nullable in PE+ typings, but always present for relics
weights
)!;
if (config.relicRewardItemCountMultiplier !== undefined && (config.relicRewardItemCountMultiplier ?? 1) != 1) {
reward = {
...reward,
itemCount: reward.itemCount * config.relicRewardItemCountMultiplier
};
}
logger.debug(`relic rolled`, reward);
participant.Reward = reward.type;
// Remove relic
const miscItemChanges = [
{
ItemType: participant.VoidProjection,
ItemCount: -1
const baseWeights = refinementToWeights[relic.quality];
// 从配置中获取奖励乘数
const relicRewardItemCountMultiplier = config.relicRewardItemCountMultiplier || 1;
logger.debug(`使用奖励数量乘数: ${relicRewardItemCountMultiplier}x`);
// 存储奖励的详细信息
const allRewards: { type: string; itemCount: number; rarity: TRarity }[] = [];
// 循环生成奖励
const extraRelicReward = config.extraRelicRewards ?? 1;
for (let i = 0; i < extraRelicReward; i++) {
let weights = {...baseWeights}; // 复制基础权重
// 根据配置覆盖权重 (仅当配置开启时)
if (relic.quality === "VPQ_SILVER" && config.exceptionalRelicsAlwaysGiveBronzeReward) {
weights = { COMMON: 1, UNCOMMON: 0, RARE: 0, LEGENDARY: 0 };
} else if (relic.quality === "VPQ_GOLD" && config.flawlessRelicsAlwaysGiveSilverReward) {
weights = { COMMON: 0, UNCOMMON: 1, RARE: 0, LEGENDARY: 0 };
} else if (relic.quality === "VPQ_PLATINUM" && config.radiantRelicsAlwaysGiveGoldReward) {
weights = { COMMON: 0, UNCOMMON: 0, RARE: 1, LEGENDARY: 0 };
}
];
logger.debug(`生成第${i+1}次奖励,遗物品质 ${relic.quality}; 权重`, weights);
const reward = getRandomWeightedReward(
ExportRewards[relic.rewardManifest][0] as { type: string; itemCount: number; rarity: TRarity }[],
weights
)!;
// 应用奖励数量乘数
const multipliedReward = {
...reward,
itemCount: Math.floor(reward.itemCount * relicRewardItemCountMultiplier)
};
logger.debug(`${i+1}次奖励结果(应用乘数后)`, multipliedReward);
allRewards.push(multipliedReward);
// 发放本次奖励到库存
const rewardAcquisition = await handleStoreItemAcquisition(
multipliedReward.type,
inventory,
multipliedReward.itemCount
);
combineInventoryChanges(
inventoryChanges,
rewardAcquisition.InventoryChanges
);
//设置核桃给白金
if (config.crackRelicForPlatinum ?? true) {
const platinumValue = getPlatinumByRarity(reward.rarity)*(config.relicRewardItemCountMultiplier ?? 1);
logger.debug(`获得的白金值 : ${platinumValue}`);
inventory.PremiumCredits ??= 0;
inventory.PremiumCredits += platinumValue;
}
}
// 更新参与者信息
participant.Reward = allRewards[0].type; // 保持兼容
// 移除遗物 (只扣一个)
const miscItemChanges = [{
ItemType: participant.VoidProjection,
ItemCount: -1
}];
addMiscItems(inventory, miscItemChanges);
combineInventoryChanges(inventoryChanges, { MiscItems: miscItemChanges });
// Give reward
combineInventoryChanges(
inventoryChanges,
(await handleStoreItemAcquisition(reward.type, inventory, reward.itemCount)).InventoryChanges
);
return reward;
// 返回所有奖励结果(保持兼容性)
return {
...allRewards[0],
allRewards: allRewards // 添加新字段
} as any as IRngResult; // 类型断言
};
const refinementToWeights = {

View File

@ -91,6 +91,69 @@ export interface IConfig extends IConfigRemovedOptions {
dev?: {
keepVendorsExpired?: boolean;
};
//Alex端的自定义接口
//集团声望是否倒扣和掉段设置为0则不倒扣不掉段
noSyndicateLoss?: boolean;
//玄骸相关
//玄骸密码总是正确不需要密码即可击杀且安魂mod不消耗耐久
nemesisAlwaysCorrect?: boolean;
//玄骸怒气倍率
extraHenchmenKilledGrineer?: number;
extraHenchmenKilledCorpus?: number;
//对于i骸是杀毒进度
extraHenchmenKilledInfestation?: number;
//玄骸解密进度倍率
extraHintProgressGrineer?: number;
extraHintProgressCorpus?: number;
//额外玄骸武器
//抽取随机的同派系武器,与当前玄骸元素属性和加成数值相同,一起发放到铸造厂
nemesisExtraWeapon?: number;
//效价融合增强,在原版1.1后额外的乘数
nemesisWeaponFuseMultiplier?: number;
//玄骸额外等级大于0的情况下猜错密码玄骸可能升更多级
nemesisExtraLevel?: number;
//任务奖励倍率
//包括生存、间谍、刺杀、赏金等,会在当前轮次奖池中额外抽取奖励
//这个倍率也会影响王境进度
extraRandomMissionDrops?: number;
//单独的王境进度倍率(与上面相乘!)
circuitProgressMuliplier?: number;
//额外堕落mod奖励
extraCorrputedMods?: number;
//额外隐藏掉落奖励(例如落银树亭的成长之力)
extraStrippedItems?: number;
//额外內源之力,九重天和漂泊者
extraPlayerSkillGainsSpace?: number;
extraPlayerSkillGainsDrifter?: number;
//核桃相关
//核桃掉落倍率,开一个核桃会多开几个奖励出来
extraRelicRewards?: number;
//开核桃给白金功能,按照开出的部件的稀有度给白金
crackRelicForPlatinum?: boolean;
//白金数量设置
platinumCommon?: number;
platinumUncommon?: number;
platinumRare?: number;
platinumLegendary?: number;
}
export const configRemovedOptionsKeys = [

View File

@ -1339,8 +1339,16 @@ export const addStanding = (
}
updateStandingLimit(inventory, syndicateMeta.dailyLimitBin, gainedStanding);
}
//声望变化不会为负数
const noSyndicateLoss = config.noSyndicateLoss ?? true;
if(!noSyndicateLoss){
syndicate.Standing += gainedStanding;
}
else{
syndicate.Standing += Math.max(0, gainedStanding);
}
syndicate.Standing += gainedStanding;
const affiliationMod: IAffiliationMods = {
Tag: syndicateTag,
Standing: gainedStanding
@ -1354,11 +1362,13 @@ export const addStanding = (
}
} else {
while (syndicate.Standing < getMinStanding(syndicateMeta, syndicate.Title ?? 0)) {
syndicate.Title ??= 0;
syndicate.Title -= 1;
affiliationMod.Title ??= 0;
affiliationMod.Title -= 1;
logger.debug(`${syndicateTag} is decreasing to title ${syndicate.Title} after applying alignment`);
if (!noSyndicateLoss){
syndicate.Title ??= 0;
affiliationMod.Title ??= 0;
syndicate.Title -= 1;
affiliationMod.Title -= 1;
logger.debug(`${syndicateTag} is decreasing to title ${syndicate.Title} after applying alignment`);
}
}
}
}
@ -2156,9 +2166,10 @@ export const updateSyndicate = (
): void => {
syndicateUpdate?.forEach(affiliation => {
const syndicate = inventory.Affiliations.find(x => x.Tag == affiliation.Tag);
if (syndicate !== undefined) {
syndicate.Standing += affiliation.Standing;
syndicate.Title = syndicate.Title === undefined ? affiliation.Title : syndicate.Title + affiliation.Title;
if (syndicate !== undefined) {
//阻止负声望和掉段
syndicate.Standing += Math.max(0, affiliation.Standing);
syndicate.Title = syndicate.Title === undefined ? affiliation.Title : syndicate.Title + Math.max(0, affiliation.Title);
} else {
inventory.Affiliations.push({
Standing: affiliation.Standing,

File diff suppressed because it is too large Load Diff

View File

@ -644,7 +644,7 @@
<div data-route="/webui/cheats, /webui/settings" data-title="Cheats | OpenWF WebUI">
<div class="row g-3">
<div class="col-md-6">
<div class="card">
<div class="card mb-3">
<h5 class="card-header" data-loc="cheats_account"></h5>
<div class="card-body" id="account-cheats">
<div class="form-check">
@ -773,6 +773,165 @@
</form>
</div>
</div>
<div class="card mb-3">
<h5 class="card-header" data-loc="cheats_alex"></h5>
<div class="card-body">
<div class="d-none config-admin-hide">
<p class="card-text" data-loc="cheats_administratorRequirement"></p>
</div>
<div class="d-none config-admin-show config-form">
<div class="form-check">
<input class="form-check-input" type="checkbox" id="noSyndicateLoss" />
<label class="form-check-label" for="noSyndicateLoss" data-loc="cheats_noSyndicateLoss"></label>
</div>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="nemesisAlwaysCorrect" />
<label class="form-check-label" for="nemesisAlwaysCorrect" data-loc="cheats_nemesisAlwaysCorrect"></label>
<abbr data-loc-inc="nemesisAlwaysCorrect_information"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
</div>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('extraHenchmenKilledGrineer'); return false;">
<label class="form-label" for="extraHenchmenKilledGrineer" data-loc="cheats_extraHenchmenKilledGrineer"></label>
<div class="input-group">
<input class="form-control" id="extraHenchmenKilledGrineer" type="number" min="0" max="1000000" step="0.1" data-default="4.0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('extraHenchmenKilledCorpus'); return false;">
<label class="form-label" for="extraHenchmenKilledCorpus" data-loc="cheats_extraHenchmenKilledCorpus"></label>
<div class="input-group">
<input class="form-control" id="extraHenchmenKilledCorpus" type="number" min="0" max="1000000" step="0.1" data-default="1.0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('extraHenchmenKilledInfestation'); return false;">
<label class="form-label" for="extraHenchmenKilledInfestation" data-loc="cheats_extraHenchmenKilledInfestation"></label>
<div class="input-group">
<input class="form-control" id="extraHenchmenKilledInfestation" type="number" min="0" max="1000000" step="0.1" data-default="2.0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('extraHintProgressGrineer'); return false;">
<label class="form-label" for="extraHintProgressGrineer" data-loc="cheats_extraHintProgressGrineer"></label>
<div class="input-group">
<input class="form-control" id="extraHintProgressGrineer" type="number" min="0" max="1000000" step="0.1" data-default="3.0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('extraHintProgressCorpus'); return false;">
<label class="form-label" for="extraHintProgressCorpus" data-loc="cheats_extraHintProgressCorpus"></label>
<div class="input-group">
<input class="form-control" id="extraHintProgressCorpus" type="number" min="0" max="1000000" step="0.1" data-default="1.0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('nemesisExtraWeapon'); return false;">
<label class="form-label" for="nemesisExtraWeapon" data-loc="cheats_nemesisExtraWeapon"></label>
<abbr data-loc-inc="nemesisExtraWeapon_information"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<div class="input-group">
<input class="form-control" id="nemesisExtraWeapon" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('nemesisWeaponFuseMultiplier'); return false;">
<label class="form-label" for="nemesisWeaponFuseMultiplier" data-loc="cheats_nemesisWeaponFuseMultiplier"></label>
<div class="input-group">
<input class="form-control" id="nemesisWeaponFuseMultiplier" type="number" min="0" max="1000000" step="0.01" data-default="1.15" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('nemesisExtraLevel'); return false;">
<label class="form-label" for="nemesisExtraLevel" data-loc="cheats_nemesisExtraLevel"></label>
<div class="input-group">
<input class="form-control" id="nemesisExtraLevel" type="number" min="0" max="1000000" data-default="2" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('extraRandomMissionDrops'); return false;">
<label class="form-label" for="extraRandomMissionDrops" data-loc="cheats_extraRandomMissionDrops"></label>
<abbr data-loc-inc="extraRandomMissionDrops_information"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<div class="input-group">
<input class="form-control" id="extraRandomMissionDrops" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('circuitProgressMuliplier'); return false;">
<label class="form-label" for="circuitProgressMuliplier" data-loc="cheats_circuitProgressMuliplier"></label>
<abbr data-loc-inc="circuitProgressMuliplier_information"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><path d="M320 576C461.4 576 576 461.4 576 320C576 178.6 461.4 64 320 64C178.6 64 64 178.6 64 320C64 461.4 178.6 576 320 576zM320 200C333.3 200 344 210.7 344 224L344 336C344 349.3 333.3 360 320 360C306.7 360 296 349.3 296 336L296 224C296 210.7 306.7 200 320 200zM293.3 416C292.7 406.1 297.6 396.7 306.1 391.5C314.6 386.4 325.3 386.4 333.8 391.5C342.3 396.7 347.2 406.1 346.6 416C347.2 425.9 342.3 435.3 333.8 440.5C325.3 445.6 314.6 445.6 306.1 440.5C297.6 435.3 292.7 425.9 293.3 416z"/></svg></abbr>
<div class="input-group">
<input class="form-control" id="circuitProgressMuliplier" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('extraCorrputedMods'); return false;">
<label class="form-label" for="extraCorrputedMods" data-loc="cheats_extraCorrputedMods"></label>
<div class="input-group">
<input class="form-control" id="extraCorrputedMods" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('extraStrippedItems'); return false;">
<label class="form-label" for="extraStrippedItems" data-loc="cheats_extraStrippedItems"></label>
<div class="input-group">
<input class="form-control" id="extraStrippedItems" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigFloat('extraPlayerSkillGainsSpace'); return false;">
<label class="form-label" for="extraPlayerSkillGainsSpace" data-loc="cheats_extraPlayerSkillGainsSpace"></label>
<div class="input-group">
<input class="form-control" id="extraPlayerSkillGainsSpace" type="number" min="0" max="1000000" step="0.1" data-default="1.0" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('extraPlayerSkillGainsDrifter'); return false;">
<label class="form-label" for="extraPlayerSkillGainsDrifter" data-loc="cheats_extraPlayerSkillGainsDrifter"></label>
<div class="input-group">
<input class="form-control" id="extraPlayerSkillGainsDrifter" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('extraRelicRewards'); return false;">
<label class="form-label" for="extraRelicRewards" data-loc="cheats_extraRelicRewards"></label>
<div class="input-group">
<input class="form-control" id="extraRelicRewards" type="number" min="0" max="1000000" data-default="3" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<div class="form-check">
<input class="form-check-input" type="checkbox" id="crackRelicForPlatinum" />
<label class="form-check-label" for="crackRelicForPlatinum" data-loc="cheats_crackRelicForPlatinum"></label>
</div>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('platinumCommon'); return false;">
<label class="form-label" for="platinumCommon" data-loc="cheats_platinumCommon"></label>
<div class="input-group">
<input class="form-control" id="platinumCommon" type="number" min="0" max="1000000" data-default="2" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('platinumUncommon'); return false;">
<label class="form-label" for="platinumUncommon" data-loc="cheats_platinumUncommon"></label>
<div class="input-group">
<input class="form-control" id="platinumUncommon" type="number" min="0" max="1000000" data-default="5" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('platinumRare'); return false;">
<label class="form-label" for="platinumRare" data-loc="cheats_platinumRare"></label>
<div class="input-group">
<input class="form-control" id="platinumRare" type="number" min="0" max="1000000" data-default="12" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
<form class="form-group mt-2" onsubmit="doSaveConfigInt('platinumLegendary'); return false;">
<label class="form-label" for="platinumLegendary" data-loc="cheats_platinumLegendary"></label>
<div class="input-group">
<input class="form-control" id="platinumLegendary" type="number" min="0" max="1000000" data-default="30" />
<button class="btn btn-secondary" type="submit" data-loc="cheats_save"></button>
</div>
</form>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card mb-3">

View File

@ -382,5 +382,36 @@ dict = {
theme_dark: `暗色主题`,
theme_light: `亮色主题`,
prettier_sucks_ass: ``
prettier_sucks_ass: ``,
cheats_alex: `Alex端的作弊选项`,
cheats_noSyndicateLoss:`集团声望不倒扣`,
cheats_nemesisAlwaysCorrect:`玄骸密码总是正确`,
cheats_extraHenchmenKilledGrineer: `玄骸怒气倍率 (Grineer)`,
cheats_extraHenchmenKilledCorpus: `玄骸怒气倍率 (Corpus)`,
cheats_extraHenchmenKilledInfestation: `玄骸杀毒进度倍率(Infestation)`,
cheats_extraHintProgressGrineer: `玄骸解密进度倍率 (Grineer)`,
cheats_extraHintProgressCorpus: `玄骸解密进度倍率 (Corpus)`,
cheats_nemesisExtraWeapon: `额外玄骸武器数量`,
cheats_nemesisWeaponFuseMultiplier: `玄骸武器效价融合增强`,
cheats_nemesisExtraLevel: `玄骸额外等级`,
cheats_extraRandomMissionDrops: `任务奖励倍率`,
cheats_circuitProgressMuliplier: `王境进度倍率`,
cheats_extraCorrputedMods: `额外堕落Mod奖励`,
cheats_extraStrippedItems: `额外隐藏掉落奖励`,
cheats_extraPlayerSkillGainsSpace: `额外九重天内源之力`,
cheats_extraPlayerSkillGainsDrifter: `额外漂泊者内源之力`,
cheats_extraRelicRewards: `遗物奖励倍率`,
cheats_crackRelicForPlatinum:`根据遗物部件获取白金`,
cheats_platinumCommon: `普通部件白金数量`,
cheats_platinumUncommon: `罕见部件白金数量`,
cheats_platinumRare: `稀有部件白金数量`,
cheats_platinumLegendary: `传说部件白金数量`,
nemesisAlwaysCorrect_information:`将所有卡视为万用卡,并且不消耗次数`,
nemesisExtraWeapon_information:`完成决战后,会发放同样元素属性和加成数值的随机同派系武器到铸造厂`,
extraRandomMissionDrops_information:`在当前轮次奖池中额外抽取奖励。这个倍率也会影响王境进度`,
circuitProgressMuliplier_information:`与任务奖励倍率相乘`,
};

22
启动服务端.sh Normal file
View File

@ -0,0 +1,22 @@
#!/bin/bash
echo "Updating SpaceNinjaServer..."
git fetch --prune
git stash
git checkout -f 自用
if [ -d "static/data/0/" ]; then
echo "Updating stripped assets..."
cd static/data/0/
git pull
cd ../../../
fi
echo "Updating dependencies..."
npm i --omit=dev
npm run build
if [ $? -eq 0 ]; then
npm run start
echo "SpaceNinjaServer seems to have crashed."
fi

View File

@ -0,0 +1,68 @@
# Alex端的食用教程和修改选项
在config-vanilla.json底部可以看到已经配置好的默认参数
复制一份并改名为config.json就可以使其生效之后对于参数的修改都在复制的这份config.json里进行
# 参数的默认值和说明
//集团声望设置为false时倒扣和掉段设置为true则不倒扣不掉段
"noSyndicateLoss": true,
---
//玄骸相关
//玄骸密码总是正确不需要密码即可击杀且安魂mod不消耗耐久
"nemesisAlwaysCorrect": false,
//玄骸怒气倍率
"extraHenchmenKilledGrineer": 4.0,
"extraHenchmenKilledCorpus": 1.0,
//对于i骸是杀毒进度
"extraHenchmenKilledInfestation": 2.0,
//玄骸解密进度倍率
"extraHintProgressGrineer": 3.0,
"extraHintProgressCorpus": 1.0,
//额外玄骸武器
//抽取随机的同派系武器,与当前玄骸元素属性和加成数值相同,一起发放到铸造厂
"nemesisExtraWeapon": 3,
//效价融合增强,在原版1.1后额外的乘数
"nemesisWeaponFuseMultiplier": 1.15,
//玄骸额外等级大于0的情况下猜错密码玄骸可能升更多级
"nemesisExtraLevel": 2,
---
//任务奖励倍率
//包括生存、间谍、刺杀、赏金等,会在当前轮次奖池中额外抽取奖励
//这个倍率也会影响王境进度
"extraRandomMissionDrops": 3,
//单独的王境进度倍率(与上面相乘!)
"circuitProgressMuliplier": 3,
//额外堕落mod奖励
"extraCorrputedMods": 3,
//额外隐藏掉落奖励(例如落银树亭的成长之力)
"extraStrippedItems": 3,
//额外內源之力,九重天和漂泊者
"extraPlayerSkillGainsSpace": 1.0,
"extraPlayerSkillGainsDrifter": 3,
---
//核桃相关
//核桃按品质给白金的数值请在relicHelper.ts中修改
//核桃掉落倍率,开一个核桃会多开几个奖励出来
"extraRelicRewards": 3
//开核桃给白金功能,按照开出的部件的稀有度给白金
"crackRelicForPlatinum": true,
//白金数量设置
"platinumCommon": 2,
"platinumUncommon": 5,
"platinumRare": 12,
"platinumLegendary": 30
---