57 lines
2.4 KiB
JavaScript
57 lines
2.4 KiB
JavaScript
'use strict';
|
|
(function attachSharedContracts(root,factory){
|
|
const api=factory();
|
|
if(typeof module==='object'&&module.exports)module.exports=api;
|
|
if(root)root.BendSharedContracts=api;
|
|
})(typeof globalThis!=='undefined'?globalThis:this,()=>{
|
|
const BOARD_ID_RE=/^B(?:0|[1-9][0-9]*)$/;
|
|
const CONTRACT_ID_RE=/^[A-Za-z0-9:_-]+$/;
|
|
const SPECIAL_MECHANIC_TYPES=Object.freeze(['warp','lock','crossing','internalGate']);
|
|
const SPECIAL_MECHANIC_SET=new Set(SPECIAL_MECHANIC_TYPES);
|
|
const DEFAULT_BUYER='\u65c5\u4eba';
|
|
|
|
function cleanContractId(value,maxLength=64){
|
|
const text=String(value||'').trim();
|
|
return text&&text.length<=maxLength&&CONTRACT_ID_RE.test(text)?text:'';
|
|
}
|
|
|
|
function cleanPlayerName(value,fallback=DEFAULT_BUYER){
|
|
const name=String(value||'').replace(/[\u0000-\u001f\u007f]/g,'').replace(/\s+/g,' ').trim().slice(0,24);
|
|
return name||fallback;
|
|
}
|
|
|
|
function normalizeSpecialMechanics(raw){
|
|
return[...new Set((Array.isArray(raw)?raw:[]).filter(type=>SPECIAL_MECHANIC_SET.has(type)))].sort();
|
|
}
|
|
|
|
function normalizePlayerPurchases(raw,{resolveItem=id=>({id}),maxPurchases=10000,maxPaidCost=Number.MAX_SAFE_INTEGER,defaultBuyer=DEFAULT_BUYER}={}){
|
|
const purchases=[],seenIds=new Set(),seenStoreItems=new Set();
|
|
for(const source of Array.isArray(raw)?raw:[]){
|
|
if(purchases.length>=maxPurchases)break;
|
|
const purchaseId=cleanContractId(source?.purchaseId,64),boardId=cleanContractId(source?.boardId,32),item=resolveItem(String(source?.itemId||'')),
|
|
storeKey=`${boardId}:${item?.id||''}`;
|
|
if(!purchaseId||!BOARD_ID_RE.test(boardId)||!item?.id||seenIds.has(purchaseId)||seenStoreItems.has(storeKey))continue;
|
|
const boughtAt=Number(source.boughtAt),paidCost=Number.isSafeInteger(source.paidCost)&&source.paidCost>=0?Math.min(source.paidCost,maxPaidCost):item.cost;
|
|
if(!Number.isSafeInteger(paidCost)||paidCost<0)continue;
|
|
seenIds.add(purchaseId);seenStoreItems.add(storeKey);
|
|
purchases.push({
|
|
purchaseId,
|
|
boardId,
|
|
itemId:item.id,
|
|
buyer:cleanPlayerName(source.buyer,defaultBuyer),
|
|
boughtAt:Number.isFinite(boughtAt)&&boughtAt>0?boughtAt:0,
|
|
paidCost
|
|
});
|
|
}
|
|
return purchases;
|
|
}
|
|
|
|
return Object.freeze({
|
|
BOARD_ID_RE,
|
|
SPECIAL_MECHANIC_TYPES,
|
|
cleanContractId,
|
|
cleanPlayerName,
|
|
normalizeSpecialMechanics,
|
|
normalizePlayerPurchases
|
|
});
|
|
});
|