fortnite-replay-analysis 1.0.5 → 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 +56 -25
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -77,7 +77,7 @@ function ReplayAnalysis(replayFileDir, { bot = false, sort = true } = {}) { // F
77
77
  Placement: player.Placement,
78
78
  Kills: player.Kills,
79
79
  TeamKills: player.TeamKills,
80
- aliveTime: aliveTimeDecimal, // Decimalオブジェクトのまま保持
80
+ aliveTime: aliveTimeDecimal,
81
81
  EpicId: player.EpicId,
82
82
  PlayerName: player.PlayerName,
83
83
  Platform: player.Platform,
@@ -146,38 +146,47 @@ function mergeScores(scoreArrays) { // 複数マッチの結果をマージし
146
146
  }
147
147
 
148
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
+
149
168
  return arr.sort((a, b) => {
150
169
  // 1. 累計獲得ポイント
151
- if (b.partyScore !== a.partyScore) {
152
- return b.partyScore - a.partyScore;
170
+ if (b.result.point !== a.result.point) {
171
+ return b.result.point - a.result.point;
153
172
  }
154
173
  // 2. セッション中の累計 Victory Royale 回数
155
- if (b.partyVictoryRoyaleCount !== a.partyVictoryRoyaleCount) {
156
- return b.partyVictoryRoyaleCount - a.partyVictoryRoyaleCount;
174
+ if (b.result.victoryCount !== a.result.victoryCount) {
175
+ return b.result.victoryCount - a.result.victoryCount;
157
176
  }
158
177
 
159
- // マッチ数(配置と生存時間の配列長を使う想定)
160
- const aCount = (a.partyPlacementList || a.partyAliveTimeList || []).length || 1;
161
- const bCount = (b.partyPlacementList || b.partyAliveTimeList || []).length || 1;
162
-
163
178
  // 3. 平均撃破数
164
- const aAvgKills = (a.partyKills || 0) / aCount;
165
- const bAvgKills = (b.partyKills || 0) / bCount;
166
- if (bAvgKills !== aAvgKills) {
167
- return bAvgKills - aAvgKills;
179
+ if (b.result.avgKills !== a.result.avgKills) {
180
+ return b.result.avgKills - a.result.avgKills;
168
181
  }
169
182
 
170
183
  // 4. 平均順位(小さいほうが上位)
171
- const aAvgPlacement = (a.partyPlacementList || []).reduce((s, x) => s + x, 0) / aCount;
172
- const bAvgPlacement = (b.partyPlacementList || []).reduce((s, x) => s + x, 0) / bCount;
173
- if (aAvgPlacement !== bAvgPlacement) {
174
- return aAvgPlacement - bAvgPlacement;
184
+ if (b.result.avgPlacement !== a.result.avgPlacement) {
185
+ return b.result.avgPlacement - a.result.avgPlacement;
175
186
  }
176
187
 
177
188
  // 5. 全マッチの合計生存時間
178
- const aTime = sumMaxAliveTime(a.partyAliveTimeByMatch);
179
- const bTime = sumMaxAliveTime(b.partyAliveTimeByMatch);
180
- const cmp = bTime.comparedTo(aTime);
189
+ const cmp = b.result.totalAliveTime.comparedTo(a.result.totalAliveTime);
181
190
  if (cmp !== 0) return cmp;
182
191
 
183
192
  // 6. 最終手段:1マッチ目のパーティ番号が小さい順
@@ -185,13 +194,35 @@ function sortScores(arr) { // 公式準拠のスコアソート関数
185
194
  });
186
195
  }
187
196
 
188
- function sumMaxAliveTime(aliveTimeByMatch) {
189
- return (Array.isArray(aliveTimeByMatch) ? aliveTimeByMatch : [])
190
- .reduce((sum, match) => {
191
- const times = Array.isArray(match.times) ? match.times : [new Decimal(0)];
192
- 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
+ );
193
209
  return sum.plus(maxTime);
194
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);
195
226
  }
196
227
 
197
228
  module.exports = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fortnite-replay-analysis",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "Fortniteのリプレイ解析をNode.jsから呼べる自己完結型C#バイナリラッパー",
5
5
  "repository": {
6
6
  "type": "git",