fortnite-replay-analysis 1.0.4 → 1.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/index.js +57 -25
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const os = require('os');
2
+ const fs = require('fs');
2
3
  const path = require('path');
3
4
  const Decimal = require('decimal.js');
4
5
  const { execFile } = require('child_process');
@@ -76,7 +77,7 @@ function ReplayAnalysis(replayFileDir, { bot = false, sort = true } = {}) { // F
76
77
  Placement: player.Placement,
77
78
  Kills: player.Kills,
78
79
  TeamKills: player.TeamKills,
79
- aliveTime: aliveTimeDecimal, // Decimalオブジェクトのまま保持
80
+ aliveTime: aliveTimeDecimal,
80
81
  EpicId: player.EpicId,
81
82
  PlayerName: player.PlayerName,
82
83
  Platform: player.Platform,
@@ -145,38 +146,47 @@ function mergeScores(scoreArrays) { // 複数マッチの結果をマージし
145
146
  }
146
147
 
147
148
  function sortScores(arr) { // 公式準拠のスコアソート関数
149
+ // リザルトとしてpoint, ビクロイ数, マッチ数, 平均撃破数, 平均順位, 合計生存時間を追加したい
150
+ if (!Array.isArray(arr) || arr.length === 0) return arr;
151
+
152
+ arr.forEach(p => {
153
+ const matchCount = (p.partyPlacementList || []).filter((placement, i, arr) =>
154
+ placement === 1 && p.partyNumber === (arr[i] || {}).partyNumber
155
+ ).length || 1;
156
+ p.result = {
157
+ point: p.partyScore || 0,
158
+ victoryCount: p.partyVictoryRoyaleCount ?? (p.partyVictoryRoyale ? 1 : 0),
159
+ matchCount,
160
+ avgKills: (p.partyKills || 0) / matchCount,
161
+ avgPlacement: (p.partyPlacementList && p.partyPlacementList.length > 0)
162
+ ? (p.partyPlacementList.reduce((s, x) => s + x, 0) / p.partyPlacementList.length)
163
+ : p.partyPlacement,
164
+ totalAliveTime: sumMaxAliveTime(p.partyAliveTimeList, p.partyAliveTimeByMatch),
165
+ };
166
+ });
167
+
148
168
  return arr.sort((a, b) => {
149
169
  // 1. 累計獲得ポイント
150
- if (b.partyScore !== a.partyScore) {
151
- return b.partyScore - a.partyScore;
170
+ if (b.result.point !== a.result.point) {
171
+ return b.result.point - a.result.point;
152
172
  }
153
173
  // 2. セッション中の累計 Victory Royale 回数
154
- if (b.partyVictoryRoyaleCount !== a.partyVictoryRoyaleCount) {
155
- return b.partyVictoryRoyaleCount - a.partyVictoryRoyaleCount;
174
+ if (b.result.victoryCount !== a.result.victoryCount) {
175
+ return b.result.victoryCount - a.result.victoryCount;
156
176
  }
157
177
 
158
- // マッチ数(配置と生存時間の配列長を使う想定)
159
- const aCount = (a.partyPlacementList || a.partyAliveTimeList || []).length || 1;
160
- const bCount = (b.partyPlacementList || b.partyAliveTimeList || []).length || 1;
161
-
162
178
  // 3. 平均撃破数
163
- const aAvgKills = (a.partyKills || 0) / aCount;
164
- const bAvgKills = (b.partyKills || 0) / bCount;
165
- if (bAvgKills !== aAvgKills) {
166
- return bAvgKills - aAvgKills;
179
+ if (b.result.avgKills !== a.result.avgKills) {
180
+ return b.result.avgKills - a.result.avgKills;
167
181
  }
168
182
 
169
183
  // 4. 平均順位(小さいほうが上位)
170
- const aAvgPlacement = (a.partyPlacementList || []).reduce((s, x) => s + x, 0) / aCount;
171
- const bAvgPlacement = (b.partyPlacementList || []).reduce((s, x) => s + x, 0) / bCount;
172
- if (aAvgPlacement !== bAvgPlacement) {
173
- return aAvgPlacement - bAvgPlacement;
184
+ if (b.result.avgPlacement !== a.result.avgPlacement) {
185
+ return b.result.avgPlacement - a.result.avgPlacement;
174
186
  }
175
187
 
176
188
  // 5. 全マッチの合計生存時間
177
- const aTime = sumMaxAliveTime(a.partyAliveTimeByMatch);
178
- const bTime = sumMaxAliveTime(b.partyAliveTimeByMatch);
179
- const cmp = bTime.comparedTo(aTime);
189
+ const cmp = b.result.totalAliveTime.comparedTo(a.result.totalAliveTime);
180
190
  if (cmp !== 0) return cmp;
181
191
 
182
192
  // 6. 最終手段:1マッチ目のパーティ番号が小さい順
@@ -184,13 +194,35 @@ function sortScores(arr) { // 公式準拠のスコアソート関数
184
194
  });
185
195
  }
186
196
 
187
- function sumMaxAliveTime(aliveTimeByMatch) {
188
- return (Array.isArray(aliveTimeByMatch) ? aliveTimeByMatch : [])
189
- .reduce((sum, match) => {
190
- const times = Array.isArray(match.times) ? match.times : [new Decimal(0)];
191
- const maxTime = times.reduce((max, t) => (t.comparedTo(max) > 0 ? t : max), new Decimal(0));
197
+ function sumMaxAliveTime(partyAliveTimeList, partyAliveTimeByMatch) {
198
+ if (Array.isArray(partyAliveTimeByMatch) && partyAliveTimeByMatch.length > 0) {
199
+ // 複数マッチ分の最大値を足す処理
200
+ return partyAliveTimeByMatch.reduce((sum, match) => {
201
+ if (!Array.isArray(match.times) || match.times.length === 0) return sum;
202
+ const maxTime = match.times.reduce(
203
+ (max, t) => {
204
+ const timeDec = new Decimal(t);
205
+ return timeDec.greaterThan(max) ? timeDec : max;
206
+ },
207
+ new Decimal(0)
208
+ );
192
209
  return sum.plus(maxTime);
193
210
  }, new Decimal(0));
211
+ }
212
+
213
+ // こっちは単一マッチ用。配列の最大値返すだけ
214
+ if (Array.isArray(partyAliveTimeList) && partyAliveTimeList.length > 0) {
215
+ const maxVal = partyAliveTimeList.reduce(
216
+ (max, t) => {
217
+ const timeDec = new Decimal(t);
218
+ return timeDec.greaterThan(max) ? timeDec : max;
219
+ },
220
+ new Decimal(0)
221
+ );
222
+ return maxVal;
223
+ }
224
+
225
+ return new Decimal(0);
194
226
  }
195
227
 
196
228
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fortnite-replay-analysis",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Fortniteのリプレイ解析をNode.jsから呼べる自己完結型C#バイナリラッパー",
5
5
  "repository": {
6
6
  "type": "git",