본문으로 이동

리버티게임:관리자 요청/2017년 5월

리버티게임, 모두가 만들어가는 자유로운 게임
백괴게임>BANIP님의 2017년 5월 20일 (토) 21:26 판

MediaWiki:common.js 스크립트 추가 요청합니다.

/** mediawiki api를 통해 간단하게 문서들을 수집, 변경하는 함수.
  * 플러그인 코어에서 사용하기 위해 만들었습니다.
  * 작성자: [[사용자:BANIP|BANIP]]
  */


var token;
 var getToken = (function(){
    $.ajax({
        url:"/w/api.php?action=query&meta=tokens",
        success:function(v,i){
            var datas = JSON.parse($(v).find("pre").text());
            token = datas["query"]["tokens"]["csrftoken"];
        },
	    async: false
    })
})();

function entityDecode(doc){
	return $('<p></p>').html(doc).text();
}
function changeDocument( title, summary, content, editToken ) {
    $.ajax({
        url: mw.util.wikiScript("api"),
        data: {
            format: 'json',
            action: 'edit',
            title: title,
            summary: summary,
            text: content,
            token: editToken
        },
        dataType: 'json',
        type: 'POST',
        success: function( data ) {
            if ( data && data.edit && data.edit.result == 'Success' ) {
                window.location.reload(); // reload page if edit was successful
            } else if ( data && data.error ) {
                alert( 'Error: API returned error code "' + data.error.code + '": ' + data.error.info );
            } else {
                alert( 'Error: Unknown result from API.' );
            }
        },
        error: function( xhr ) {
            alert( 'Error: Request failed.' );
        }
    });
}
function addDocument( title, summary, content, editToken ){
	originContent = getDocument(title)
	changeDocument( title, summary, originContent + content, editToken );
}

function getDocument(title){
	var originContent;
	 $.ajax({
	    url:"/w/index.php?title=" + title + "&action=edit",
	    success:function ajaxSucess(data){
			originContent = $(data).find("textarea").html();
		},
	    async: false
	})
	return entityDecode(originContent);
}

function readDocument(title){
	var doc;
	 $.ajax({
	    url:"/wiki/" + title,
	    success:function ajaxSucess(data){
			doc = $(data).find("#mw-content-text");
		},
	    async: false
	})
	return doc;
}

/** 플러그인 틀을 사용할 수 있게 하는 함수.
  * 작성자: [[사용자:BANIP|BANIP]]
  */

	var commonjs = "사용자:" + mw.config.get("wgRelevantUserName") + "/common.js";
	var plugins = {}, docPlugins = {}, uninstalledPlugins = {}, unupdatedPlugins = {};
	var preloadedplugins = [], needPlugins = [];
	var jsdoc

	function removePluginByDoc(title,doc){
		var reg = new RegExp("\\/\\*\\* 플러그인 "+title+"([\\s\\S]*)\\/\\* "+title+" 끝 \\*\\/","g");
		doc = doc.replace(reg,"");
		return doc
	}

	var checkDocPlugin = (function(){
		var plusSubTitle = ""
		$(".use-script").each(function(){
			var plugin = {
				name : $(this).attr("data-name"),
				descript : $(this).attr("data-descript"),
				version : $(this).attr("data-version"),
				local : ($(this).attr("data-local") == "true") ? true : false,
				creat : $(this).attr("data-creat"),
				state : $(this).attr("data-state"),
				link : $(this).attr("data-link"),
			};
			docPlugins[plugin.name] = plugin;
			plusSubTitle += ", " + $(this).attr("data-name");
		})
		if(plusSubTitle != ""){
			plusSubTitle += " 플러그인 가동중";
			$("#siteSub").text(function(i,v){return v + plusSubTitle});
		}
	})();


	var checkHavePlugin = (function(){
		if(Object.keys(docPlugins).length >= 1){
			jsdoc = getDocument(commonjs);
			var pluginreg = /plugins\.([a-zA-Z0-9_$]*)\s?\=\s?(\{.*\})\;/g;
			var nameMatch = pluginreg.exec(jsdoc);
			while(nameMatch){
				preloadedplugins.push(JSON.parse( nameMatch[2] ));
			    nameMatch = pluginreg.exec(jsdoc);
			}
			for(var keyD in docPlugins){
				var docplugin = docPlugins[keyD];
				var isHavePlugin = false;
				for(var keyM in preloadedplugins){
					var myplugin = preloadedplugins[keyM]
					if(docplugin.name == myplugin.name){
						if(docplugin.version != myplugin.version){
							unupdatedPlugins[docplugin.name] = docplugin;
						}
						isHavePlugin = true;
						break; 
					} 
				}
				if(isHavePlugin == false){
					uninstalledPlugins[docplugin.name] = docplugin;
				}
			}
			for(var key in uninstalledPlugins){
				needPlugins.push( docPlugins[key].name );
			}
			for(var key in unupdatedPlugins){
				needPlugins.push( docPlugins[key].name );
			}
		}
	})();

	var checkinstalledPlugin = function(){
			if( Object.keys(docPlugins).length >= 1 && (Object.keys(unupdatedPlugins).length >= 1 || Object.keys(uninstalledPlugins).length >= 1) ){
				function appendBox(plugin,status){
					var box = $(".cloneable.p-box").clone().removeClass("cloneable");
					var code = readDocument( plugin.state ).find("pre.script").html();
					docPlugins[plugin.name].code = code;
					box.find(".p-status").html(status);
					box.find(".p-code").html( code.replace(/\s{1,}$/,"") );
					box.find(".p-name").text( plugin["name"] );
					box.find(".p-descript").text( plugin["descript"] );
					if(status == "버전업"){
						var thisVersion;
						for(var key in preloadedplugins){
							if (preloadedplugins[key].name == plugin["name"]){
								thisVersion = preloadedplugins[key].version;
							}
						}
						box.find(".p-version").text( thisVersion + " => " + plugin["version"] );
					} else {
						box.find(".p-version").text( plugin["version"] );
					}
					box.find(".p-local").text( plugin["local"] == true ? "일부 문서만" : "문서 전체" );
					box.find(".p-creat").text( plugin["creat"] );
					    $.ajax({
					        url:"/w/api.php?action=query&prop=revisions&rvdir=older&titles=" + plugin.state,
					        success:function(v,i){
					            var datas = JSON.parse($(v).find("pre").text());
					            var titleKey = Object.keys(datas["query"]["pages"])[0];
					            var lastModified = datas["query"]["pages"][titleKey]["revisions"][0]["user"] +"(" + datas["query"]["pages"][titleKey]["revisions"][0]["timestamp"] + ")";
					            box.find(".p-last").text(lastModified);
					        },
					        async: false
					    })
					$(".box-article").append(box);

				}

				var doc = $("#mw-content-text");
				var setupMeta = readDocument("틀:플러그인/setup");
				doc.html(setupMeta);

				for(var key in uninstalledPlugins){
					appendBox(uninstalledPlugins[key],"설치");
				}

				for(var key in unupdatedPlugins){
					appendBox(unupdatedPlugins[key],"버전업");
				}

				function installButtonClick(){
					$(".install-button").text("설치중..");
					$(".install-button").off("click");

					function translateInstallPlugin(plugin){
						var toJSONPlugin = Object.assign({}, plugin);
						toJSONPlugin.code = undefined;
						toJSONPlugin.link = undefined;

						var docHead = "", docFoot = "";
						docHead += "/** 플러그인 "  + plugin["name"] +  "***************************\n";
						docHead += "* " + plugin["descript"] + "\n";
						docHead += "* 버전 => " + plugin["version"] + "\n";
						docHead += "* 작성자 : [[사용자:" + plugin["creat"] + "|" + plugin["creat"] + "]] \n";
						docHead += "*/ \n";
						docHead += "plugins." + plugin["name"] + " = " + JSON.stringify(toJSONPlugin) + "; \n";
						docHead += "var plugin_" + plugin["name"] + " = function(){\n";
						docFoot += "\n}\n";

						if(plugin.local){
							docFoot += "if($(\"[data-name='" + plugin["name"] + "']\").length >= 1){\n";
							docFoot += "plugin_" + plugin["name"] + "();\n";
							docFoot += "}\n";
						} else {
							docFoot += "plugin_" + plugin["name"] + "();\n";
						}
						docFoot += "/* " + plugin["name"] + " 끝 */\n";
						return entityDecode(docHead + plugin["code"] + docFoot);
					}

					var doc = "";
					for(var key in needPlugins){
						var pluginName = needPlugins[key];
						var plugin = docPlugins[pluginName];
						jsdoc = removePluginByDoc(pluginName,jsdoc);
						doc += translateInstallPlugin( plugin );
					}
						changeDocument(commonjs,"플러그인 "+ needPlugins +"설치", jsdoc + doc, token);
				}

				$(".install-button").on("click",installButtonClick);
			}
	}
	if(Object.keys(docPlugins).length >= 1 && (Object.keys(unupdatedPlugins).length >= 1 || Object.keys(uninstalledPlugins).length >= 1)){
		if($(".plugin-install").length >= 1){
			$(".plugin-install").eq(0).closest("table").show();
			$(".plugin-name").eq(0).text(needPlugins);
			$(".plugin-install").on("click",checkinstalledPlugin);
		} else {
			checkinstalledPlugin();		
		}
	}

사용자의 common.js 문서를 미디어위키 api로 고칠 수 있는것을 이용해 일반 문서에서 자바스크립트 활용을 가능케 하는 문서입니다.

이 기능으로 링크와 CGI틀과 같은 양산형 문서 연결게임들보다 훨씬 스펙트럼이 넓은 게임을 자유자재로 만들 수 있습니다. 플래시 없이도 리듬게임이나 액션게임, 정성만 들이면 온라인 rpg게임까지 확장 가능합니다. 스타크래프트의 EUD와 비슷하다고 보셔도 무방합니다.

물론 스크립트 추가 전 사용자에게 설치 여부를 묻는것으로 보안 이슈도 말끔히 처리했습니다. 위 스크립트를 MediaWiki:common.js 맨 밑 내용에 추가해주시면 됩니다. --BANIP (토론|토론작성) 2017년 5월 19일 (금) 17:18 (KST)

완료했습니다!-- 사용자:산천대국 시장/서명 2017년 5월 20일 (토) 07:02 (KST)
빠른 처리 감사드립니다. 사용자 common.js문서와 전체 문서의 common.js파일의 작동 방식이 다른건지, 테스트때는 오류없이 작동하던게 꿈쩍도 하지 않네요ㅠㅠ --BANIP (토론|토론작성)