@@ -24,7 +24,7 @@ import {
} from "./page-data.js" ;
} from "./page-data.js" ;
type StateSetter < T > = ( next : T | ( ( previous : T ) = > T ) ) = > void ;
type StateSetter < T > = ( next : T | ( ( previous : T ) = > T ) ) = > void ;
type InputEvent = { target ? : { value? : string ; checked? : boolean } ; stopPropagation ? : ( ) = > void } ;
type InputEvent = { target ? : { value? : string ; checked? : boolean ; open? : boolean } ; stopPropagation ? : ( ) = > void } ;
type GiftTab = "definitions" | "claims" | "deliveries" | "timed" ;
type GiftTab = "definitions" | "claims" | "deliveries" | "timed" ;
type MapLayer = "players" | "vehicles" | "flags" | "regions" | "other" ;
type MapLayer = "players" | "vehicles" | "flags" | "regions" | "other" ;
type PlayerPanelKind = "closed" | "attributes" | "gifts" | "items" | "history" | "trajectory" ;
type PlayerPanelKind = "closed" | "attributes" | "gifts" | "items" | "history" | "trajectory" ;
@@ -103,6 +103,10 @@ export function renderSCUMFeaturePage(react: ReactLike, input: SCUMPageContext)
const [ mapCenterY , setMapCenterY ] = usePluginState ( react , "" ) ;
const [ mapCenterY , setMapCenterY ] = usePluginState ( react , "" ) ;
const [ mapWidthKm , setMapWidthKm ] = usePluginState ( react , "" ) ;
const [ mapWidthKm , setMapWidthKm ] = usePluginState ( react , "" ) ;
const [ mapHeightKm , setMapHeightKm ] = usePluginState ( react , "" ) ;
const [ mapHeightKm , setMapHeightKm ] = usePluginState ( react , "" ) ;
const [ eventEditorOpen , setEventEditorOpen ] = usePluginState ( react , false ) ;
const [ produceEditorOpen , setProduceEditorOpen ] = usePluginState ( react , false ) ;
const [ giftEditorOpen , setGiftEditorOpen ] = usePluginState ( react , false ) ;
const [ mapSettingsOpen , setMapSettingsOpen ] = usePluginState ( react , false ) ;
const pageKey = input . pageKey ? ? "players" ;
const pageKey = input . pageKey ? ? "players" ;
const refresh = ( ) = > {
const refresh = ( ) = > {
@@ -123,7 +127,7 @@ export function renderSCUMFeaturePage(react: ReactLike, input: SCUMPageContext)
} , [ input . serverInstanceId , pageKey , input . workspaceActions , playerPanel . kind ] ) ;
} , [ input . serverInstanceId , pageKey , input . workspaceActions , playerPanel . kind ] ) ;
const data = state . status === "ready" ? state.data : emptySCUMSurfaceData ;
const data = state . status === "ready" ? state.data : emptySCUMSurfaceData ;
return e ( "section" , { className : "console-panel" , "aria-label" : input . pageTitle ? ? surfaceTitle ( pageKey ) } ,
return e ( "section" , { className : "console-panel scum-workbench " , "aria-label" : input . pageTitle ? ? surfaceTitle ( pageKey ) } ,
action . status !== "idle" ? e ( "p" , { className : "page-status" , "data-state" : action . status } , action . message ) : null ,
action . status !== "idle" ? e ( "p" , { className : "page-status" , "data-state" : action . status } , action . message ) : null ,
state . status === "loading" ? e ( "p" , { className : "page-status" } , "正在读取插件自有 SCUM 集合…" ) : null ,
state . status === "loading" ? e ( "p" , { className : "page-status" } , "正在读取插件自有 SCUM 集合…" ) : null ,
state . status === "error" ? e ( "p" , { className : "page-status" , "data-state" : "error" } , state . reason ) : null ,
state . status === "error" ? e ( "p" , { className : "page-status" , "data-state" : "error" } , state . reason ) : null ,
@@ -135,6 +139,7 @@ export function renderSCUMFeaturePage(react: ReactLike, input: SCUMPageContext)
giftTab , setGiftTab , giftCode , setGiftCode , giftName , setGiftName , giftItems , setGiftItems , giftCommands , setGiftCommands , giftClass , setGiftClass , giftAudience , setGiftAudience , giftNumber , setGiftNumber , giftAchievement , setGiftAchievement , giftAchievementNumber , setGiftAchievementNumber ,
giftTab , setGiftTab , giftCode , setGiftCode , giftName , setGiftName , giftItems , setGiftItems , giftCommands , setGiftCommands , giftClass , setGiftClass , giftAudience , setGiftAudience , giftNumber , setGiftNumber , giftAchievement , setGiftAchievement , giftAchievementNumber , setGiftAchievementNumber ,
deliveryGift , setDeliveryGift , deliveryPlayer , setDeliveryPlayer , mapSearch , setMapSearch , mapLayers , setMapLayers , selectedMapPoint , setSelectedMapPoint ,
deliveryGift , setDeliveryGift , deliveryPlayer , setDeliveryPlayer , mapSearch , setMapSearch , mapLayers , setMapLayers , selectedMapPoint , setSelectedMapPoint ,
mapCustomEnabled , setMapCustomEnabled , mapCenterX , setMapCenterX , mapCenterY , setMapCenterY , mapWidthKm , setMapWidthKm , mapHeightKm , setMapHeightKm ,
mapCustomEnabled , setMapCustomEnabled , mapCenterX , setMapCenterX , mapCenterY , setMapCenterY , mapWidthKm , setMapWidthKm , mapHeightKm , setMapHeightKm ,
eventEditorOpen , setEventEditorOpen , produceEditorOpen , setProduceEditorOpen , giftEditorOpen , setGiftEditorOpen , mapSettingsOpen , setMapSettingsOpen ,
setAction , refresh
setAction , refresh
} ) : null
} ) : null
) ;
) ;
@@ -158,6 +163,7 @@ type ViewState = {
mapSearch : string ; setMapSearch : StateSetter < string > ; mapLayers : Record < MapLayer , boolean > ; setMapLayers : StateSetter < Record < MapLayer , boolean > > ;
mapSearch : string ; setMapSearch : StateSetter < string > ; mapLayers : Record < MapLayer , boolean > ; setMapLayers : StateSetter < Record < MapLayer , boolean > > ;
selectedMapPoint : string ; setSelectedMapPoint : StateSetter < string > ; setAction : StateSetter < ActionState > ; refresh : ( ) = > void ;
selectedMapPoint : string ; setSelectedMapPoint : StateSetter < string > ; setAction : StateSetter < ActionState > ; refresh : ( ) = > void ;
mapCustomEnabled : boolean | undefined ; setMapCustomEnabled : StateSetter < boolean | undefined > ; mapCenterX : string ; setMapCenterX : StateSetter < string > ; mapCenterY : string ; setMapCenterY : StateSetter < string > ; mapWidthKm : string ; setMapWidthKm : StateSetter < string > ; mapHeightKm : string ; setMapHeightKm : StateSetter < string > ;
mapCustomEnabled : boolean | undefined ; setMapCustomEnabled : StateSetter < boolean | undefined > ; mapCenterX : string ; setMapCenterX : StateSetter < string > ; mapCenterY : string ; setMapCenterY : StateSetter < string > ; mapWidthKm : string ; setMapWidthKm : StateSetter < string > ; mapHeightKm : string ; setMapHeightKm : StateSetter < string > ;
eventEditorOpen : boolean ; setEventEditorOpen : StateSetter < boolean > ; produceEditorOpen : boolean ; setProduceEditorOpen : StateSetter < boolean > ; giftEditorOpen : boolean ; setGiftEditorOpen : StateSetter < boolean > ; mapSettingsOpen : boolean ; setMapSettingsOpen : StateSetter < boolean > ;
} ;
} ;
function renderSurfaceBody ( e : ReactLike [ "createElement" ] , pageKey : string , data : SCUMSurfaceData , input : SCUMPageContext , view : ViewState ) {
function renderSurfaceBody ( e : ReactLike [ "createElement" ] , pageKey : string , data : SCUMSurfaceData , input : SCUMPageContext , view : ViewState ) {
@@ -176,12 +182,13 @@ function playersSurface(e: ReactLike["createElement"], data: SCUMSurfaceData, in
const search = view . playerSearch . trim ( ) . toLowerCase ( ) ;
const search = view . playerSearch . trim ( ) . toLowerCase ( ) ;
const players = data . players . filter ( ( player ) = > matchesText ( player , search , "displayName" , "playerName" , "gamePlayerId" , "playerId" , "steamId" , "squadName" ) && ( view . playerStatus === "all" || ( view . playerStatus === "online" ) === playerOnline ( player ) ) ) ;
const players = data . players . filter ( ( player ) = > matchesText ( player , search , "displayName" , "playerName" , "gamePlayerId" , "playerId" , "steamId" , "squadName" ) && ( view . playerStatus === "all" || ( view . playerStatus === "online" ) === playerOnline ( player ) ) ) ;
const selectedPlayer = data . players . find ( ( player ) = > playerKey ( player ) === view . playerPanel . playerId ) ;
const selectedPlayer = data . players . find ( ( player ) = > playerKey ( player ) === view . playerPanel . playerId ) ;
return e ( "div" , { className : "console-record-list" } ,
return e ( "div" , { className : "console-record-list scum-surface " } ,
e ( "div" , { className : "console-row-actions " } ,
e ( "div" , { className : "resource-filter-bar scum-filter-bar " } ,
e ( "input" , { value : view.playerSearch , "aria-label" : "搜索用户" , placeholder : "名称 / Steam ID / 队伍" , onChange : ( event : InputEvent ) = > view . setPlayerSearch ( inputValue ( event ) ) } ) ,
labeledField ( e , "搜索用户" , e ( "input" , { type : "search" , value : view.playerSearch , "aria-label" : "搜索用户" , placeholder : "名称 / Steam ID / 队伍" , onChange : ( event : InputEvent ) = > view . setPlayerSearch ( inputValue ( event ) ) } ) ) ,
e ( "select" , { value : view.playerStatus , "aria-label" : "在线状态" , onChange : ( event : InputEvent ) = > view . setPlayerStatus ( inputValue ( event ) ) } , e ( "option" , { value : "all" } , "全部状态" ) , e ( "option" , { value : "online" } , "在线" ) , e ( "option" , { value : "offline" } , "离线/未知" ) )
labeledField ( e , "在线状态" , e ( "select" , { value : view.playerStatus , "aria-label" : "在线状态" , onChange : ( event : InputEvent ) = > view . setPlayerStatus ( inputValue ( event ) ) } , e ( "option" , { value : "all" } , "全部状态" ) , e ( "option" , { value : "online" } , "在线" ) , e ( "option" , { value : "offline" } , "离线/未知" ) ) ) ,
e ( "span" , { className : "page-status" } , ` ${ players . length } / ${ data . players . length } 用户 ` )
) ,
) ,
e ( "div" , { className : "provider-table-wrap" } ,
e ( "div" , { className : "provider-table-wrap scum-table-wrap " } ,
e ( "table" , { className : "resource-table scum-user-table" } ,
e ( "table" , { className : "resource-table scum-user-table" } ,
e ( "caption" , { className : "provider-id" } , "SCUM 用户真实记录" ) ,
e ( "caption" , { className : "provider-id" } , "SCUM 用户真实记录" ) ,
e ( "thead" , null , e ( "tr" , null , [ "用户名" , "队伍" , "状态" , "最后活动" , "操作" ] . map ( ( label ) = > e ( "th" , { key : label , scope : "col" } , label ) ) ) ) ,
e ( "thead" , null , e ( "tr" , null , [ "用户名" , "队伍" , "状态" , "最后活动" , "操作" ] . map ( ( label ) = > e ( "th" , { key : label , scope : "col" } , label ) ) ) ) ,
@@ -205,7 +212,7 @@ function playerTableRow(e: ReactLike["createElement"], player: RecordMap, index:
}
}
function playerActionMenu ( e : ReactLike [ "createElement" ] , player : RecordMap , view : ViewState , open : ( kind : PlayerPanelKind ) = > void ) {
function playerActionMenu ( e : ReactLike [ "createElement" ] , player : RecordMap , view : ViewState , open : ( kind : PlayerPanelKind ) = > void ) {
return e ( "details" , { className : "provider -actions -cel l" } ,
return e ( "details" , { className : "inline -action-contro l" } ,
e ( "summary" , { className : "icon-command" , "aria-label" : ` 打开 ${ textField ( player , "displayName" , "playerName" ) || "用户" } 操作菜单 ` } , "操作" ) ,
e ( "summary" , { className : "icon-command" , "aria-label" : ` 打开 ${ textField ( player , "displayName" , "playerName" ) || "用户" } 操作菜单 ` } , "操作" ) ,
e ( "div" , { className : "inline-action-menu" , role : "menu" , "aria-label" : "用户操作" } ,
e ( "div" , { className : "inline-action-menu" , role : "menu" , "aria-label" : "用户操作" } ,
e ( "button" , { type : "button" , className : "runtime-action-item" , role : "menuitem" , onClick : ( ) = > open ( "attributes" ) } , "编辑属性" ) ,
e ( "button" , { type : "button" , className : "runtime-action-item" , role : "menuitem" , onClick : ( ) = > open ( "attributes" ) } , "编辑属性" ) ,
@@ -299,7 +306,7 @@ function squadsSurface(e: ReactLike["createElement"], data: SCUMSurfaceData, vie
return e ( "div" , { className : "overview-two-col" } ,
return e ( "div" , { className : "overview-two-col" } ,
e ( "article" , { className : "console-module" } ,
e ( "article" , { className : "console-module" } ,
e ( "div" , { className : "panel-header" } , e ( "h2" , null , "队伍" ) , e ( "span" , { className : "page-status" } , ` ${ squads . length } 支 ` ) ) ,
e ( "div" , { className : "panel-header" } , e ( "h2" , null , "队伍" ) , e ( "span" , { className : "page-status" } , ` ${ squads . length } 支 ` ) ) ,
e ( "input" , { value : view.squadSearch , "aria-label" : "搜索队伍" , placeholder : "队名 / 队长 / 队伍 ID" , onChange : ( event : InputEvent ) = > view . setSquadSearch ( inputValue ( event ) ) } ) ,
e ( "div" , { className : "resource-filter-bar scum-filter-bar" } , labeledField ( e , "搜索队伍" , e ( "input" , { type : "search" , value : view.squadSearch , "aria-label" : "搜索队伍" , placeholder : "队名 / 队长 / 队伍 ID" , onChange : ( event : InputEvent ) = > view . setSquadSearch ( inputValue ( event ) ) } ) ) ) ,
e ( "div" , { className : "console-row-list" } , squads . length ? squads . map ( ( squad , index ) = > {
e ( "div" , { className : "console-row-list" } , squads . length ? squads . map ( ( squad , index ) = > {
const squadId = textField ( squad , "squadId" , "id" ) ;
const squadId = textField ( squad , "squadId" , "id" ) ;
const memberCount = data . members . filter ( ( member ) = > textField ( member , "squadId" ) === squadId ) . length ;
const memberCount = data . members . filter ( ( member ) = > textField ( member , "squadId" ) === squadId ) . length ;
@@ -356,7 +363,7 @@ function activitiesSurface(e: ReactLike["createElement"], data: SCUMSurfaceData,
return e ( "div" , { className : "console-record-list" } ,
return e ( "div" , { className : "console-record-list" } ,
statsStrip ( e , [ [ "活动定义" , data . events . length ] , [ "运行记录" , data . eventRuns . length ] , [ "原生赛事轮次" , data . nativeEventRounds . length ] , [ "任务" , data . tasks . length ] ] ) ,
statsStrip ( e , [ [ "活动定义" , data . events . length ] , [ "运行记录" , data . eventRuns . length ] , [ "原生赛事轮次" , data . nativeEventRounds . length ] , [ "任务" , data . tasks . length ] ] ) ,
e ( "div" , { className : "overview-two-col" } ,
e ( "div" , { className : "overview-two-col" } ,
e ( "details" , { className : "console-module scum-editor" , open : Boolean ( view . eventId || view . eventName ) } , e ( "summary" , null , e ( "strong" , null , "新建或更新活动" ) , e ( "span" , { className : "page-status" } , view . eventId || view . eventName ? "编辑中" : "点击展开" ) ) ,
e ( "details" , { className : "console-module scum-editor" , open : view.eventEditorOpen , onToggle : ( event : InputEvent ) = > view . setEventEditorOpen ( detailOpen ( event ) ) } , e ( "summary" , null , e ( "strong" , null , "新建或更新活动" ) , e ( "span" , { className : "page-status" } , view . eventId || view . eventName ? "编辑中" : "点击展开" ) ) ,
labeledField ( e , "活动编号" , e ( "input" , { value : view.eventId , "aria-label" : "活动编号" , placeholder : "例如 event_supply_drop" , onChange : ( event : InputEvent ) = > view . setEventId ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "活动编号" , e ( "input" , { value : view.eventId , "aria-label" : "活动编号" , placeholder : "例如 event_supply_drop" , onChange : ( event : InputEvent ) = > view . setEventId ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "活动名称" , e ( "input" , { value : view.eventName , "aria-label" : "活动名称" , placeholder : "例如 空投补给" , onChange : ( event : InputEvent ) = > view . setEventName ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "活动名称" , e ( "input" , { value : view.eventName , "aria-label" : "活动名称" , placeholder : "例如 空投补给" , onChange : ( event : InputEvent ) = > view . setEventName ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "生成类型" , e ( "select" , { value : view.eventClass , "aria-label" : "生成类型" , onChange : ( event : InputEvent ) = > view . setEventClass ( inputValue ( event ) ) } , e ( "option" , { value : "1" } , "范围生成" ) , e ( "option" , { value : "2" } , "固定坐标生成" ) ) ) ,
labeledField ( e , "生成类型" , e ( "select" , { value : view.eventClass , "aria-label" : "生成类型" , onChange : ( event : InputEvent ) = > view . setEventClass ( inputValue ( event ) ) } , e ( "option" , { value : "1" } , "范围生成" ) , e ( "option" , { value : "2" } , "固定坐标生成" ) ) ) ,
@@ -376,7 +383,7 @@ function activitiesSurface(e: ReactLike["createElement"], data: SCUMSurfaceData,
e ( "p" , { className : "page-status" } , "活动定义属于插件;SCUM 原生 event_round 和 quest/task 只作为运行事实展示。" )
e ( "p" , { className : "page-status" } , "活动定义属于插件;SCUM 原生 event_round 和 quest/task 只作为运行事实展示。" )
)
)
) ,
) ,
e ( "details" , { className : "console-module scum-editor" , open : Boolean ( view . produceEventId || view . produceId || view . produceTradeGoodsId ) } , e ( "summary" , null , e ( "strong" , null , "活动生成项" ) , e ( "span" , { className : "page-status" } , view . produceEventId || view . produceId ? "编辑中" : "点击展开" ) ) ,
e ( "details" , { className : "console-module scum-editor" , open : view.produceEditorOpen , onToggle : ( event : InputEvent ) = > view . setProduceEditorOpen ( detailOpen ( event ) ) } , e ( "summary" , null , e ( "strong" , null , "活动生成项" ) , e ( "span" , { className : "page-status" } , view . produceEventId || view . produceId ? "编辑中" : "点击展开" ) ) ,
e ( "div" , { className : "console-row-actions" } ,
e ( "div" , { className : "console-row-actions" } ,
labeledField ( e , "活动编号" , e ( "input" , { value : view.produceEventId , "aria-label" : "生成项活动编号" , placeholder : "默认使用上方活动" , onChange : ( event : InputEvent ) = > view . setProduceEventId ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "活动编号" , e ( "input" , { value : view.produceEventId , "aria-label" : "生成项活动编号" , placeholder : "默认使用上方活动" , onChange : ( event : InputEvent ) = > view . setProduceEventId ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "生成项编号" , e ( "input" , { value : view.produceId , "aria-label" : "生成项编号" , placeholder : "更新时填写" , onChange : ( event : InputEvent ) = > view . setProduceId ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "生成项编号" , e ( "input" , { value : view.produceId , "aria-label" : "生成项编号" , placeholder : "更新时填写" , onChange : ( event : InputEvent ) = > view . setProduceId ( inputValue ( event ) ) } ) ) ,
@@ -393,7 +400,7 @@ function activitiesSurface(e: ReactLike["createElement"], data: SCUMSurfaceData,
e ( "span" , null , ` ${ textField ( produce , "eventId" , "event" ) } / ${ textField ( produce , "tradeGoodsId" , "trade_goods_id" ) } ` ) ,
e ( "span" , null , ` ${ textField ( produce , "eventId" , "event" ) } / ${ textField ( produce , "tradeGoodsId" , "trade_goods_id" ) } ` ) ,
e ( "strong" , null , ` ${ numField ( produce , "percent" ) } % × ${ numField ( produce , "value" ) } ` ) ,
e ( "strong" , null , ` ${ numField ( produce , "percent" ) } % × ${ numField ( produce , "value" ) } ` ) ,
e ( "strong" , null , ` R ${ numField ( produce , "r" ) } · ${ coords ( produce ) } ` ) ,
e ( "strong" , null , ` R ${ numField ( produce , "r" ) } · ${ coords ( produce ) } ` ) ,
e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > { view . setProduceEventId ( textField ( produce , "eventId" , "event" ) ) ; view . setProduceId ( textField ( produce , "id" , "produceId" ) ) ; view . setProduceTradeGoodsId ( textField ( produce , "tradeGoodsId" , "trade_goods_id" ) ) ; view . setProducePercent ( numField ( produce , "percent" ) ) ; view . setProduceValue ( numField ( produce , "value" ) ) ; view . setProduceRadius ( numField ( produce , "r" ) ) ; view . setProduceX ( numField ( produce , "x" ) ) ; view . setProduceY ( numField ( produce , "y" ) ) ; view . setProduceZ ( numField ( produce , "z" ) ) ; } } , "编辑" ) ,
e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > { view . setProduceEditorOpen ( true ) ; view . setProduceEventId ( textField ( produce , "eventId" , "event" ) ) ; view . setProduceId ( textField ( produce , "id" , "produceId" ) ) ; view . setProduceTradeGoodsId ( textField ( produce , "tradeGoodsId" , "trade_goods_id" ) ) ; view . setProducePercent ( numField ( produce , "percent" ) ) ; view . setProduceValue ( numField ( produce , "value" ) ) ; view . setProduceRadius ( numField ( produce , "r" ) ) ; view . setProduceX ( numField ( produce , "x" ) ) ; view . setProduceY ( numField ( produce , "y" ) ) ; view . setProduceZ ( numField ( produce , "z" ) ) ; } } , "编辑" ) ,
e ( "button" , { type : "button" , className : "icon-command" , disabled : ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在删除生成项…" , async ( ) = > { await deleteEventProduce ( actions ? ? { } , produce ) ; view . refresh ( ) ; return "生成项已删除。" ; } ) } , "删除" ) ) ) : e ( "p" , { className : "page-status" } , "暂无活动生成项。" ) )
e ( "button" , { type : "button" , className : "icon-command" , disabled : ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在删除生成项…" , async ( ) = > { await deleteEventProduce ( actions ? ? { } , produce ) ; view . refresh ( ) ; return "生成项已删除。" ; } ) } , "删除" ) ) ) : e ( "p" , { className : "page-status" } , "暂无活动生成项。" ) )
) ,
) ,
events . length ? events . map ( ( event , index ) = > {
events . length ? events . map ( ( event , index ) = > {
@@ -405,7 +412,7 @@ function activitiesSurface(e: ReactLike["createElement"], data: SCUMSurfaceData,
e ( "div" , { className : "console-record-meta" } , e ( "span" , null , ` 生成 ${ Number ( field ( event , "class" ) ) === 2 ? "固定坐标" : "范围" } ` ) , e ( "span" , null , ` 计划 ${ textField ( event , "schedule" , "corn" ) || "手动" } ` ) , e ( "span" , null , ` 概率 ${ numField ( event , "percent" , "probability" ) } % ` ) , e ( "span" , null , ` NPC/物品/僵尸/动物 ${ numField ( event , "npc" ) } / ${ numField ( event , "item" ) } / ${ numField ( event , "zombie" ) } / ${ numField ( event , "animal" ) } ` ) , e ( "span" , null , textField ( event , "placard" , "announcement" ) || "无公告" ) ) ,
e ( "div" , { className : "console-record-meta" } , e ( "span" , null , ` 生成 ${ Number ( field ( event , "class" ) ) === 2 ? "固定坐标" : "范围" } ` ) , e ( "span" , null , ` 计划 ${ textField ( event , "schedule" , "corn" ) || "手动" } ` ) , e ( "span" , null , ` 概率 ${ numField ( event , "percent" , "probability" ) } % ` ) , e ( "span" , null , ` NPC/物品/僵尸/动物 ${ numField ( event , "npc" ) } / ${ numField ( event , "item" ) } / ${ numField ( event , "zombie" ) } / ${ numField ( event , "animal" ) } ` ) , e ( "span" , null , textField ( event , "placard" , "announcement" ) || "无公告" ) ) ,
e ( "div" , { className : "console-row-actions" } ,
e ( "div" , { className : "console-row-actions" } ,
e ( "button" , { type : "button" , className : "primary-command" , disabled : ! actions ? . gameClient || ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在启动活动…" , async ( ) = > { await startEvent ( actions ? ? { } , event , data . eventProduces . filter ( ( produce ) = > textField ( produce , "eventId" , "event" ) === eventId ) ) ; view . refresh ( ) ; return "活动命令已进入执行队列。" ; } ) } , "立即启动" ) ,
e ( "button" , { type : "button" , className : "primary-command" , disabled : ! actions ? . gameClient || ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在启动活动…" , async ( ) = > { await startEvent ( actions ? ? { } , event , data . eventProduces . filter ( ( produce ) = > textField ( produce , "eventId" , "event" ) === eventId ) ) ; view . refresh ( ) ; return "活动命令已进入执行队列。" ; } ) } , "立即启动" ) ,
e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > { view . setEventId ( eventId ) ; view . setEventName ( textField ( event , "name" ) ) ; view . setEventClass ( numField ( event , "class" ) === "--" ? "1" : numField ( event , "class" ) ) ; view . setEventSchedule ( textField ( event , "schedule" , "corn" ) ) ; view . setEventPlacard ( textField ( event , "placard" , "announcement" ) ) ; view . setEventPercent ( numField ( event , "percent" , "probability" ) ) ; view . setEventDuration ( numField ( event , "durationSeconds" ) === "--" ? "1800" : numField ( event , "durationSeconds" ) ) ; view . setEventNpc ( numField ( event , "npc" ) ) ; view . setEventItem ( numField ( event , "item" ) ) ; view . setEventZombie ( numField ( event , "zombie" ) ) ; view . setEventAnimal ( numField ( event , "animal" ) ) ; } } , "编辑" ) ,
e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > { view . setEventEditorOpen ( true ) ; view . setEventId ( eventId ) ; view . setEventName ( textField ( event , "name" ) ) ; view . setEventClass ( numField ( event , "class" ) === "--" ? "1" : numField ( event , "class" ) ) ; view . setEventSchedule ( textField ( event , "schedule" , "corn" ) ) ; view . setEventPlacard ( textField ( event , "placard" , "announcement" ) ) ; view . setEventPercent ( numField ( event , "percent" , "probability" ) ) ; view . setEventDuration ( numField ( event , "durationSeconds" ) === "--" ? "1800" : numField ( event , "durationSeconds" ) ) ; view . setEventNpc ( numField ( event , "npc" ) ) ; view . setEventItem ( numField ( event , "item" ) ) ; view . setEventZombie ( numField ( event , "zombie" ) ) ; view . setEventAnimal ( numField ( event , "animal" ) ) ; } } , "编辑" ) ,
e ( "button" , { type : "button" , className : "icon-command" , disabled : ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在删除活动…" , async ( ) = > { await deleteEventDefinition ( actions ? ? { } , eventId , data . eventProduces ) ; view . refresh ( ) ; return "活动定义已删除。" ; } ) } , "删除" )
e ( "button" , { type : "button" , className : "icon-command" , disabled : ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在删除活动…" , async ( ) = > { await deleteEventDefinition ( actions ? ? { } , eventId , data . eventProduces ) ; view . refresh ( ) ; return "活动定义已删除。" ; } ) } , "删除" )
)
)
) ;
) ;
@@ -451,7 +458,7 @@ function giftsSurface(e: ReactLike["createElement"], data: SCUMSurfaceData, inpu
giftTabButton ( e , view , "definitions" , "礼包定义" ) , giftTabButton ( e , view , "claims" , "领取/待领" ) , giftTabButton ( e , view , "deliveries" , "发放记录" ) , giftTabButton ( e , view , "timed" , "游戏定时记录" )
giftTabButton ( e , view , "definitions" , "礼包定义" ) , giftTabButton ( e , view , "claims" , "领取/待领" ) , giftTabButton ( e , view , "deliveries" , "发放记录" ) , giftTabButton ( e , view , "timed" , "游戏定时记录" )
) ,
) ,
view . giftTab === "definitions" ? e ( "div" , { className : "overview-two-col" } ,
view . giftTab === "definitions" ? e ( "div" , { className : "overview-two-col" } ,
e ( "details" , { className : "console-module scum-editor" , open : Boolean ( view . giftCode || view . giftName ) } , e ( "summary" , null , e ( "strong" , null , "新建或更新礼包" ) , e ( "span" , { className : "page-status" } , view . giftCode || view . giftName ? "编辑中" : "点击展开" ) ) ,
e ( "details" , { className : "console-module scum-editor" , open : view.giftEditorOpen , onToggle : ( event : InputEvent ) = > view . setGiftEditorOpen ( detailOpen ( event ) ) } , e ( "summary" , null , e ( "strong" , null , "新建或更新礼包" ) , e ( "span" , { className : "page-status" } , view . giftCode || view . giftName ? "编辑中" : "点击展开" ) ) ,
labeledField ( e , "礼包编号" , e ( "input" , { value : view.giftCode , "aria-label" : "礼包编号" , placeholder : "例如 welcome_pack" , onChange : ( event : InputEvent ) = > view . setGiftCode ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "礼包编号" , e ( "input" , { value : view.giftCode , "aria-label" : "礼包编号" , placeholder : "例如 welcome_pack" , onChange : ( event : InputEvent ) = > view . setGiftCode ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "礼包名称" , e ( "input" , { value : view.giftName , "aria-label" : "礼包名称" , placeholder : "例如 新人礼包" , onChange : ( event : InputEvent ) = > view . setGiftName ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "礼包名称" , e ( "input" , { value : view.giftName , "aria-label" : "礼包名称" , placeholder : "例如 新人礼包" , onChange : ( event : InputEvent ) = > view . setGiftName ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "礼包周期" , e ( "select" , { value : view.giftClass , "aria-label" : "礼包周期" , onChange : ( event : InputEvent ) = > view . setGiftClass ( inputValue ( event ) ) } , [ [ "1" , "每日" ] , [ "2" , "每周" ] , [ "3" , "每月" ] , [ "4" , "每年" ] , [ "5" , "一次" ] , [ "6" , "每日五次" ] ] . map ( ( [ value , label ] ) = > e ( "option" , { key : value , value } , label ) ) ) ) ,
labeledField ( e , "礼包周期" , e ( "select" , { value : view.giftClass , "aria-label" : "礼包周期" , onChange : ( event : InputEvent ) = > view . setGiftClass ( inputValue ( event ) ) } , [ [ "1" , "每日" ] , [ "2" , "每周" ] , [ "3" , "每月" ] , [ "4" , "每年" ] , [ "5" , "一次" ] , [ "6" , "每日五次" ] ] . map ( ( [ value , label ] ) = > e ( "option" , { key : value , value } , label ) ) ) ) ,
@@ -469,7 +476,7 @@ function giftsSurface(e: ReactLike["createElement"], data: SCUMSurfaceData, inpu
e ( "div" , { className : "console-record-meta" } , e ( "span" , null , ` 周期 ${ giftClassLabel ( numField ( gift , "class" ) ) } ` ) , e ( "span" , null , ` 适用 ${ textField ( gift , "audience" ) || "all" } ` ) , e ( "span" , null , ` 次数 ${ numField ( gift , "number" ) } ` ) , e ( "span" , null , ` 成就 ${ numField ( gift , "achievement" ) } / ${ numField ( gift , "achievementNumber" , "achievement_number" ) } ` ) ) ,
e ( "div" , { className : "console-record-meta" } , e ( "span" , null , ` 周期 ${ giftClassLabel ( numField ( gift , "class" ) ) } ` ) , e ( "span" , null , ` 适用 ${ textField ( gift , "audience" ) || "all" } ` ) , e ( "span" , null , ` 次数 ${ numField ( gift , "number" ) } ` ) , e ( "span" , null , ` 成就 ${ numField ( gift , "achievement" ) } / ${ numField ( gift , "achievementNumber" , "achievement_number" ) } ` ) ) ,
e ( "span" , { className : "provider-id" } , giftItemsSummary ( gift ) ) ,
e ( "span" , { className : "provider-id" } , giftItemsSummary ( gift ) ) ,
e ( "span" , { className : "provider-id" } , giftCommandsSummary ( gift ) ) ,
e ( "span" , { className : "provider-id" } , giftCommandsSummary ( gift ) ) ,
e ( "div" , { className : "console-row-actions" } , e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > view . setDeliveryGift ( key ) } , "选择发放" ) , e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > { view . setGiftCode ( textField ( gift , "code" ) ) ; view . setGiftName ( textField ( gift , "name" ) ) ; view . setGiftClass ( numField ( gift , "class" ) ) ; view . setGiftAudience ( textField ( gift , "audience" ) || "all" ) ; view . setGiftNumber ( numField ( gift , "number" ) ) ; view . setGiftAchievement ( numField ( gift , "achievement" ) ) ; view . setGiftAchievementNumber ( numField ( gift , "achievementNumber" , "achievement_number" ) ) ; view . setGiftItems ( giftItemsInput ( gift ) ) ; view . setGiftCommands ( giftCommandsInput ( gift ) ) ; } } , "编辑" ) , e ( "button" , { type : "button" , className : "icon-command" , disabled : ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在删除礼包…" , async ( ) = > { await deleteGiftDefinition ( actions ? ? { } , key ) ; view . refresh ( ) ; return "礼包定义已删除。" ; } ) } , "删除" ) )
e ( "div" , { className : "console-row-actions" } , e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > view . setDeliveryGift ( key ) } , "选择发放" ) , e ( "button" , { type : "button" , className : "icon-command" , onClick : ( ) = > { view . setGiftEditorOpen ( true ) ; view . setGiftCode ( textField ( gift , "code" ) ) ; view . setGiftName ( textField ( gift , "name" ) ) ; view . setGiftClass ( numField ( gift , "class" ) ) ; view . setGiftAudience ( textField ( gift , "audience" ) || "all" ) ; view . setGiftNumber ( numField ( gift , "number" ) ) ; view . setGiftAchievement ( numField ( gift , "achievement" ) ) ; view . setGiftAchievementNumber ( numField ( gift , "achievementNumber" , "achievement_number" ) ) ; view . setGiftItems ( giftItemsInput ( gift ) ) ; view . setGiftCommands ( giftCommandsInput ( gift ) ) ; } } , "编辑" ) , e ( "button" , { type : "button" , className : "icon-command" , disabled : ! actions ? . pluginData , onClick : ( ) = > runAction ( view . setAction , "正在删除礼包…" , async ( ) = > { await deleteGiftDefinition ( actions ? ? { } , key ) ; view . refresh ( ) ; return "礼包定义已删除。" ; } ) } , "删除" ) )
) ;
) ;
} ) : e ( "p" , { className : "page-status" } , "暂无礼包定义。" ) )
} ) : e ( "p" , { className : "page-status" } , "暂无礼包定义。" ) )
) : null ,
) : null ,
@@ -507,11 +514,11 @@ function mapSurface(e: ReactLike["createElement"], data: SCUMSurfaceData, input:
const selected = visible . find ( ( point , index ) = > idOf ( point , ` point- ${ index } ` ) === view . selectedMapPoint ) ? ? visible [ 0 ] ;
const selected = visible . find ( ( point , index ) = > idOf ( point , ` point- ${ index } ` ) === view . selectedMapPoint ) ? ? visible [ 0 ] ;
return e ( "div" , { className : "console-record-list" } ,
return e ( "div" , { className : "console-record-list" } ,
statsStrip ( e , [ [ "地图点" , points . length ] , [ "用户" , data . players . length ] , [ "载具" , data . vehicles . length ] , [ "旗帜/区域" , data . flags . length + data . mapRegions . length ] ] ) ,
statsStrip ( e , [ [ "地图点" , points . length ] , [ "用户" , data . players . length ] , [ "载具" , data . vehicles . length ] , [ "旗帜/区域" , data . flags . length + data . mapRegions . length ] ] ) ,
e ( "div" , { className : "console-row-actions " } ,
e ( "div" , { className : "resource-filter-bar scum-filter-bar " } ,
labeledField ( e , "筛选地图点" , e ( "input" , { value : view.mapSearch , "aria-label" : "筛选地图点" , placeholder : "名称 / 类型 / ID" , onChange : ( event : InputEvent ) = > view . setMapSearch ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "筛选地图点" , e ( "input" , { value : view.mapSearch , "aria-label" : "筛选地图点" , placeholder : "名称 / 类型 / ID" , onChange : ( event : InputEvent ) = > view . setMapSearch ( inputValue ( event ) ) } ) ) ,
( [ "players" , "vehicles" , "flags" , "regions" , "other" ] as MapLayer [ ] ) . map ( ( layer ) = > e ( "label" , { key : layer } , e ( "input" , { type : "checkbox" , checked : view.mapLayers [ layer ] , onChange : ( event : InputEvent ) = > view . setMapLayers ( ( previous ) = > ( { . . . previous , [ layer ] : Boolean ( event . target ? . checked ) } ) ) } ) , layerLabel ( layer ) ) )
( [ "players" , "vehicles" , "flags" , "regions" , "other" ] as MapLayer [ ] ) . map ( ( layer ) = > e ( "label" , { key : layer , className : "scum-layer-toggle" } , e ( "input" , { type : "checkbox" , checked : view.mapLayers [ layer ] , onChange : ( event : InputEvent ) = > view . setMapLayers ( ( previous ) = > ( { . . . previous , [ layer ] : Boolean ( event . target ? . checked ) } ) ) } ) , layerLabel ( layer ) ) )
) ,
) ,
e ( "details" , { className : "console-module scum-editor" } , e ( "summary" , null , e ( "strong" , null , "地图范围" ) , e ( "span" , { className : "page-status" } , customEnabled ? "自定义范围" : "SCUM 默认范围" ) ) ,
e ( "details" , { className : "console-module scum-editor" , open : view.mapSettingsOpen , onToggle : ( event : InputEvent ) = > view . setMapSettingsOpen ( detailOpen ( event ) ) } , e ( "summary" , null , e ( "strong" , null , "地图范围" ) , e ( "span" , { className : "page-status" } , customEnabled ? "自定义范围" : "SCUM 默认范围" ) ) ,
e ( "div" , { className : "console-row-actions" } ,
e ( "div" , { className : "console-row-actions" } ,
e ( "label" , null , e ( "input" , { type : "checkbox" , checked : customEnabled , "aria-label" : "启用自定义地图" , onChange : ( event : InputEvent ) = > view . setMapCustomEnabled ( Boolean ( event . target ? . checked ) ) } ) , "启用自定义地图" ) ,
e ( "label" , null , e ( "input" , { type : "checkbox" , checked : customEnabled , "aria-label" : "启用自定义地图" , onChange : ( event : InputEvent ) = > view . setMapCustomEnabled ( Boolean ( event . target ? . checked ) ) } ) , "启用自定义地图" ) ,
labeledField ( e , "中心 X" , e ( "input" , { value : centerX , "aria-label" : "地图中心 X" , type : "number" , onChange : ( event : InputEvent ) = > view . setMapCenterX ( inputValue ( event ) ) } ) ) ,
labeledField ( e , "中心 X" , e ( "input" , { value : centerX , "aria-label" : "地图中心 X" , type : "number" , onChange : ( event : InputEvent ) = > view . setMapCenterX ( inputValue ( event ) ) } ) ) ,
@@ -528,6 +535,7 @@ function mapSurface(e: ReactLike["createElement"], data: SCUMSurfaceData, input:
}
}
function labeledField ( e : ReactLike [ "createElement" ] , label : string , control : unknown ) { return e ( "label" , { className : "console-field" } , e ( "span" , null , label ) , control ) ; }
function labeledField ( e : ReactLike [ "createElement" ] , label : string , control : unknown ) { return e ( "label" , { className : "console-field" } , e ( "span" , null , label ) , control ) ; }
function detailOpen ( event : InputEvent ) : boolean { return Boolean ( event . target ? . open ) ; }
function giftTabButton ( e : ReactLike [ "createElement" ] , view : ViewState , tab : GiftTab , label : string ) { return e ( "button" , { type : "button" , role : "tab" , "aria-selected" : view . giftTab === tab , className : view.giftTab === tab ? "primary-command" : "icon-command" , onClick : ( ) = > view . setGiftTab ( tab ) } , label ) ; }
function giftTabButton ( e : ReactLike [ "createElement" ] , view : ViewState , tab : GiftTab , label : string ) { return e ( "button" , { type : "button" , role : "tab" , "aria-selected" : view . giftTab === tab , className : view.giftTab === tab ? "primary-command" : "icon-command" , onClick : ( ) = > view . setGiftTab ( tab ) } , label ) ; }
function statsStrip ( e : ReactLike [ "createElement" ] , items : Array < [ string , number ] > ) { return e ( "div" , { className : "console-stat-strip" } , items . map ( ( [ label , value ] ) = > e ( "span" , { key : label , className : "server-card-stat" } , e ( "span" , null , label ) , e ( "strong" , null , String ( value ) ) ) ) ) ; }
function statsStrip ( e : ReactLike [ "createElement" ] , items : Array < [ string , number ] > ) { return e ( "div" , { className : "console-stat-strip" } , items . map ( ( [ label , value ] ) = > e ( "span" , { key : label , className : "server-card-stat" } , e ( "span" , null , label ) , e ( "strong" , null , String ( value ) ) ) ) ) ; }
function tablePanel ( e : ReactLike [ "createElement" ] , title : string , rows : RecordMap [ ] , render : ( row : RecordMap ) = > unknown [ ] ) { return e ( "article" , { className : "console-module" } , e ( "div" , { className : "panel-header" } , e ( "h2" , null , title ) , e ( "span" , { className : "page-status" } , ` ${ rows . length } 条 ` ) ) , e ( "div" , { className : "console-row-list" } , rows . length ? rows . map ( ( row , index ) = > e ( "div" , { key : idOf ( row , ` ${ title } - ${ index } ` ) , className : "console-row" } , render ( row ) . map ( ( part , partIndex ) = > partIndex === 0 ? e ( "span" , { key : partIndex } , String ( part ? ? "unknown" ) ) : e ( "strong" , { key : partIndex } , String ( part ? ? "unknown" ) ) ) ) ) : e ( "p" , { className : "page-status" } , "暂无真实记录。" ) ) ) ; }
function tablePanel ( e : ReactLike [ "createElement" ] , title : string , rows : RecordMap [ ] , render : ( row : RecordMap ) = > unknown [ ] ) { return e ( "article" , { className : "console-module" } , e ( "div" , { className : "panel-header" } , e ( "h2" , null , title ) , e ( "span" , { className : "page-status" } , ` ${ rows . length } 条 ` ) ) , e ( "div" , { className : "console-row-list" } , rows . length ? rows . map ( ( row , index ) = > e ( "div" , { key : idOf ( row , ` ${ title } - ${ index } ` ) , className : "console-row" } , render ( row ) . map ( ( part , partIndex ) = > partIndex === 0 ? e ( "span" , { key : partIndex } , String ( part ? ? "unknown" ) ) : e ( "strong" , { key : partIndex } , String ( part ? ? "unknown" ) ) ) ) ) : e ( "p" , { className : "page-status" } , "暂无真实记录。" ) ) ) ; }