`))
function getSessionID(){
return $NJ('form#PublishedFileUnsubscribe input[name="sessionid"]').val()
}
function getPageList(){
return $NJ('[id^=Subscription]').map(function(){
let ele = $NJ(this);
//https://steamcommunity.com/sharedfiles/filedetails/?id=
return {
name:ele.find('.workshopItemTitle').text(),
//link:ele.find('a:has(div.workshopItemTitle)').attr('href'),
id:URI(ele.find('a:has(div.workshopItemTitle)').attr('href')).query(true).id,
//img:ele.find('img.workshopItemPreviewImage').attr('src')
}
}).get();
}
function currentMaxItems(){
let all = new Set(['10','20','30']);
let items = new Set($NJ('.workshopBrowsePaging div:eq(1) a').map(function(){return $NJ(this).text()}).get());
let target = [...all].filter(x => !items.has(x));
return target[0];
}
function selectMaxItems(value){
let all = new Set(['10','20','30']);
if(!all.has(value)){
throw new Error('Invalid Select Option');
}
$NJ
(`.workshopBrowsePaging div:eq(1) a:contains("${value}")`)[0].click();
}
function hasNextPage(){
let nextPageButton = $NJ('.workshopBrowsePagingControls:first').find('span:contains(">"),a:contains(">")');
return nextPageButton.length!=0 && !nextPageButton.hasClass('disabled');
}
function goNextPage(){
$NJ('.workshopBrowsePagingControls:first').find('span:contains(">"),a:contains(">")')[0].click();
}
//status: STOP PROCESSING
function getStatus(){
return localStorage.getItem('exporterStatus')||"STOP";
}
let allFlags = new Set(['TASK_CLEAR_IMPORT']);
function setFlag(flag){
if(!allFlags.has(flag)){
throw new Error('Invalid Flag');
}
localStorage.setItem('exporterFlag_'+flag,true);
}
function clearFlag(flag){
if(!allFlags.has(flag)){
throw new Error('Invalid Flag');
}
localStorage.setItem('exporterFlag_'+flag,false);
}
function getFlag(flag){
if(!allFlags.has(flag)){
throw new Error('Invalid Flag');
}
return JSON.parse(localStorage.getItem('exporterFlag_'+flag)||'false');
}
function getAppID(){
return URI().query(true).appid;
}
function getAppName(){
return $NJ
('.HeaderUserInfoSection:last').text();
}
function getUserID(){
return URI().segment(1);
}
function setStatus(status){
let all = new Set(['STOP','PROCESSING']);
if(!all.has(status)){
throw new Error('Invalid Status');
}
localStorage.setItem('exporterStatus',status);
}
function getListData(){
return JSON.parse(localStorage.getItem('exporterLists')||'[]');
}
function setListData(data){
localStorage.setItem('exporterLists',JSON.stringify(data));
}
function getImportListData(){
return JSON.parse(localStorage.getItem('exporterImportLists')||'[]');
}
function setImportListData(data){
localStorage.setItem('exporterImportLists',JSON.stringify(data));
}
function startExport(){
//$NJ( "#export_notification_dialog" ).dialog();
ShowBlockingWaitDialog('汇出MOD清单','脚本正在进行模组资料收集作业,请稍后...');
if(getStatus()=="STOP"){
setStatus('PROCESSING');
setListData([]);
location.href = URI().search(function(data) {
data.p = 1;
return data;
}).toString();
}
}
function startImport(){
{
function handleFileSelect(evt) {
evt.stopPropagation();
evt.preventDefault();
if(evt.type == "drop"){
var file = evt.originalEvent.dataTransfer.files[0];
}else{
var file = evt.target.files[0];
}
var reader = new FileReader();
reader.onload = function(event) {
$TextArea.val(event.target.result);
};
reader.readAsText(file);
}
let $Body = $NJ('');
$Body.append( $NJ(`
请填入存档字串或者JSON字串
`));
let $FileRead = $NJ('',{'type':'file','style':'display:none;'});
let $FileDrop = $NJ(`
点击上传档案或将文件拖放到此处
`);
$FileDrop.on("drop",handleFileSelect);
$FileDrop.on("dragover",function (evt) {
evt.originalEvent.stopPropagation();
evt.originalEvent.preventDefault();
evt.originalEvent.dataTransfer.dropEffect = 'copy';
});
$FileDrop.click(function(){$FileRead.click()});
$FileRead.change(handleFileSelect);
$Body.append($FileRead);
$Body.append($FileDrop);
let $TextArea = $NJ('' , { 'class': 'newmodal_prompt_textarea' } );
$Body.append( $NJ('', {'class': 'newmodal_prompt_with_textarea gray_bevel fullwidth ' } ).append( $TextArea ) );
var deferred = new jQuery.Deferred();
var fnOK = function() { deferred.resolve( $TextArea.val() ); };
var fnCancel = function() { deferred.reject(); };
let $okButton = $NJ('', {type: 'submit', 'class': 'btn_green_white_innerfade btn_medium' } ).append( $NJ( '' ).text( '确定' ) );
$okButton.click( function(){
importing($TextArea.val());
Modal.Dismiss();
} );
deferred.always( function() { Modal.Dismiss(); } );
let $CancelButton = _BuildDialogButton( '取消' );
$CancelButton.click( fnCancel);
let Modal = _BuildDialog( '汇入模组清单', $Body, [$okButton, $CancelButton ],fnCancel );
deferred.promise( Modal );
Modal.Show();
}
}
function tryParseJson(str) {
try {
var obj = JSON.parse(str);
} catch (e) {
return {success:false};
}
return {success:true,data:obj};
}
function importing(data){
try{
if(typeof data === "string"){
var data = tryParseData(data);
}
setImportListData(data);
if(data.appid!==getAppID()){
throw new Error(`该存档字串游戏为 ${data.name}(${data.appid}) 不符合当前游戏 ${getAppName()}(${getAppID()})!`);
return;
}
ShowConfirmDialog('請確認',`此次匯入共計${data.mods.length}個模組,內容為 ${data.mods.map(mod=>mod.name).join('、')}`,'確認','取消')
.done(
function(){
ShowConfirmDialog('清空模组列表','请问是否要清空现有的模组列表?','清空','保留')
.done(
function(){
setFlag('TASK_CLEAR_IMPORT');
startExport();
})
.fail(
function(){
SubscribeAll(data.mods,getAppID());
});
});
}catch(e){
ShowAlertDialog('错误',e.message);
}
}
function tryParseData(text){
if(text.trim()===''){
throw new Error('字串不能为空!');
return;
}
text = text.trim();
let data = tryParseJson(text);
if(data.success){
return data.data;
}else{
try{
let data = JSON.parse(LZString.decompressFromBase64(text));
return data;
}catch (e) {
throw new Error('字串解析错误!');
return;
}
}
}
function saveListText(data){
let text = data.mods.map(item=>`${item.name} https://steamcommunity.com/sharedfiles/filedetails/?id=${item.id}`).join('\r\n');
saveText(text,`${getUserID()} ${getAppName()}(${getAppID()}) ${data.date} ${data.mods.length}个模组 清单.txt`);
}
function saveJson(data){
let text = JSON.stringify(data);
saveText(text,`${getUserID()} ${getAppName()}(${getAppID()}) ${data.date} ${data.mods.length}个模组 JSON.json`);
}
function saveText(text,filename){
let dialog = ShowBlockingWaitDialog('匯出資料','脚本正在生成檔案中,请稍后...')
setTimeout(()=>dialog.Dismiss(),3000);
let data = new Blob([text], {type: 'text/plain;charset=utf-8'});
saveAs(data, filename);
}
function timeout(time){
return new Promise(function(resolve, reject) {
setTimeout(resolve,time);
});
}
function SubscribeAll(mods, appID ){
let progressText = $NJ('');
progressText.append('正在进行订阅程序...');
let progressTextUpdated = $NJ(`${mods[0].name}(0/${mods.length})`);
progressText.append(progressTextUpdated);
let progress = ShowBlockingWaitDialog('处理中',progressText)
var p = Promise.resolve();
mods.forEach((mod,index) =>
p = p.then(() => timeout(100)).then(()=>SubscribeItem(mod,appID)).then(()=>progressTextUpdated.text((index+1)>=mods.length?`訂閱完成,共计${mods.length}个模组`:`${mods[index+1].name}(${index+1}/${mods.length})`))
);
p.catch(function(e){
progress.Dissmiss();
ShowAlertDialog( '錯誤', '訂閱時發生錯誤:'+e.message );
});
p.then(function(){
progress.Dismiss();
ShowAlertDialog( '成功', `訂閱完成,共计${mods.length}个模组` ).done(
function(){
location.href = URI().search(function(data) {
data.p = 1;
return data;
}).toString();
});
});
}
function SubscribeItem( mod, appID )
{
return new Promise(function(resolve, reject) {
$('PublishedFileSubscribe').id.value = mod.id;
$('PublishedFileSubscribe').appid.value = appID;
$('PublishedFileSubscribe').request( {
onSuccess: resolve
} );
});
}
function UnsubscribeAll()
{
var confirmDialog = ShowConfirmDialog( '全部取消訂閱?', '您確定要取消所有 Starbound 的訂閱嗎?
此動作無法復原!' );
return new Promise(function(resolve, reject) {
confirmDialog.done( function() {
var waitingDialog = ShowBlockingWaitDialog( '請稍候', '正在取消您的訂閱…' );
$NJ.post(
'https://steamcommunity.com/sharedfiles/unsubscribeall/',
{ 'sessionid' : getSessionID(), 'appid': getAppID(), 'filetype' : 18 }
).done( function( data ) {
waitingDialog.Dismiss();
if ( data.success == 1 )
{
waitingDialog.Dismiss();
resolve();
}
else
{
ShowAlertDialog( '錯誤', '取消訂閱時發生錯誤' );
reject(new Error('取消訂閱時發生錯誤'))
}
});
}).fail(
function(){
reject(new Error('使用者取消'));
}
);
});
}
function clearImportTask(){
clearFlag('TASK_CLEAR_IMPORT');
UnsubscribeAll()
.then(()=>SubscribeAll(getImportListData().mods,getAppID()))
.catch((e)=>ShowAlertDialog( '錯誤', e.message ));
}
if(getStatus()=="STOP"){
}else if(getStatus()=="PROCESSING"){
let processing_dialog = ShowBlockingWaitDialog('汇出MOD清单','脚本正在进行模组资料收集作业,请稍后...');
if(currentMaxItems() != '30'){
selectMaxItems('30');
return;
}
let currentList = getListData();
currentList.push(...getPageList());
setListData(currentList);
if(hasNextPage()){
goNextPage();
}else{
let date = new Date();
let data = {
appid:getAppID(),
name:getAppName(),
date:`${date.getFullYear()}-${date.getMonth()}-${date.getDay()}`,
mods:currentList
}
setStatus('STOP');
processing_dialog.Dismiss();
{
let mode = "base64";
let $Body = $NJ('');
$Body.append( $NJ(`