您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Automates the use of chat and message BB-Codes: [coords][url][player][alliance][b][i][s][u] - Contact list for whispering - Type /chelp <enter> in chat for help.
// ==UserScript== // @name C&C: Tiberium Alliances Chat Helper Enhanced Yiannis Mod // @namespace https://prodgame*.alliances.commandandconquer.com/*/index.aspx* // @description Automates the use of chat and message BB-Codes: [coords][url][player][alliance][b][i][s][u] - Contact list for whispering - Type /chelp <enter> in chat for help. // @include https://prodgame*.alliances.commandandconquer.com/*/index.aspx* // @version 3.2.1 // @icon https://sites.google.com/site/titlemod/home/favicon.png // @grant none // ==/UserScript== // type: /chelp in any text box and hit <enter> for a list of commands // Please report urls that are not tagged properly // window.chatHelper_suppressBrowserAltKeys suppresses normal browser menu keys [Alt+(a,p,b,i,u,s)] when you are in a textarea so that the menus don't open. (function () { var chatHelper_main = function () { window.chatHelper_debug = 0; //initial debug level, top level for easy console access var chlog = function chlog(str,lvl){ if (lvl > 0) { //lvl 1+ if (window.chatHelper_debug == 1) { // lvl 1 console.log("ChatHelper_debug: "+str+"\n"); } if (window.chatHelper_debug == 2) { // lvl 2 console.log("ChatHelper_debug: "+str+"\n"); } } else { //lvl 0 or no arg passed to lvl console.log("ChatHelper_log: "+str+"\n"); } }; try { function createchatHelper() { var onkeyupDelay = 50; //ms to wait after a keyupevent before searching contacts list. Lower for faster searching. Higher for better performance. window.chatHelper_suppressBrowserAltKeys = true; window.chatHelper_version = "3.2.0"; window.chatHelper_name = "C&C: Tiberium Alliances Chat Helper Enhanced"; chlog(window.chatHelper_name + ' v' + window.chatHelper_version + ': loading.',0); var saveObj = { saveObjVer : "3.2.0", contacts : [] }; var validCharPatt = /[-\w\.]/; var isWhisp = false; var contacts = []; var timer; var _sub; function getCaretPos(obj) { // getCaretPos from: http://userscripts.org/scripts/show/151099 obj.focus(); if (obj.selectionStart) { return obj.selectionStart; //Gecko } else if (document.selection) //IE { var sel = document.selection.createRange(); var clone = sel.duplicate(); sel.collapse(true); clone.moveToElementText(obj); clone.setEndPoint('EndToEnd', sel); return clone.text.length; } return 0; } function moveCaret(inputObject, pos) { // moveCaretPos from: http://userscripts.org/scripts/show/151099 if (inputObject.selectionStart) { inputObject.setSelectionRange(pos, pos); inputObject.focus(); } } function getCursorWordPos(inputField) { var pos = getCaretPos(inputField); var inText = inputField.value; var lc = inText.charAt(pos - 1); if (lc.match(validCharPatt) !== null) { var sPos = pos; var ePos = pos; var t = inputField.value; while (sPos >= 0 && t.charAt(sPos - 1).match(validCharPatt) !== null) { sPos--; } while (ePos <= t.length && t.charAt(ePos).match(validCharPatt) !== null) { ePos++; } //inputField.setSelectionRange(sPos,ePos); return [sPos, ePos]; } } function tagWith(tag, inputField) { var eTag = tag.replace('[', '[/'); //closing tag var tagLen = tag.length; var eTagLen = eTag.length; if (inputField !== null) { var pos = getCaretPos(inputField); var inText = inputField.value; //save scroll position if (inputField.type === 'textarea') var st = inputField.scrollTop; //if there is selected text if (inputField.selectionStart !== inputField.selectionEnd) { var a = inText.slice(0, inputField.selectionStart); var b = inText.slice(inputField.selectionStart, inputField.selectionEnd); var c = inText.slice(inputField.selectionEnd, inText.length); inputField.value = a + tag + b + eTag + c; moveCaret(inputField, pos + tagLen + eTagLen + b.length); //if ((input IS empty) OR (the last char was a space)) AND next char ISNOT a left sqbracket } else if ((inText === "" || inText.charAt(pos - 1) === " ") && (inText.charAt(pos) !== '[')) { inputField.value = inText.substr(0, pos) + tag + eTag + inText.substr(pos, inText.length); moveCaret(inputField, pos + tagLen); //if last character is a valid playername character } else if (inText.charAt(pos - 1).match(validCharPatt) !== null) { var arr = getCursorWordPos(inputField); // var s = arr[0]; var e = arr[1]; inputField.value = inText.slice(0, s) + tag + inText.slice(s, e) + eTag + inText.slice(e, inText.length); moveCaret(inputField, e + tagLen + eTagLen); } //restore scroll position if (inputField.type === 'textarea') inputField.scrollTop = st; } } function showHelp() { alert("Type /chelp in any text box to show this message.\n\nEnter key in chat:\tsearches your chat string for Urls and Coords and wraps them before submission.\n\nAlt + 1\t:\tsearches for Urls and Coords in a message or forum post and tags accordingly. Cursor is moved to the beginning.\nAlt + 2\t:\tManual URL insertion popup window\nAlt + 0\t:\tclears all tags\n\nWord wraps: tags a selected word -or- tags the word where the cursor is (if chat is empty or you hit <space> empty tags are inserted).\nAttempts to preserve cursor and scroll position.\n|\tAlt + p or Alt + 3\t:\tplayer tags\n|\tAlt + a or Alt + 4\t:\talliance tags\n|\tAlt + b\t\t\t:\tbold tags\n|\tAlt + i\t\t\t:\titalic tags\n|\tAlt + u\t\t\t:\tunderline tags\n|__\tAlt + s\t\t\t:\tstrikethrough tags\n\nContact list commands:\n/list -or- /contacts\n/add\n/del\n/del all - wipes your whole contact list"); } function saveData() { saveObj.contacts = contacts; var jString = JSON.stringify(saveObj); chlog("saveJSON: "+jString, 1); localStorage.setItem('chatHelper', jString); } function loadData() { try{ if (localStorage.getItem('myContacts')) { //should be removed eventually var dat = localStorage.getItem('myContacts'); dat = dat.split(','); saveObj.contacts = dat; //unset old storage localStorage.removeItem('myContacts'); } else if (localStorage.getItem('chatHelper')) { var saveObjTmp = JSON.parse(localStorage.getItem('chatHelper')); if (saveObjTmp.saveObjVer != window.chatHelper_version){ //version changed var va = saveObjTmp.saveObjVer.split('.'); var vb = window.chatHelper_version.split('.'); if (va[0] != vb[0]){ //major version change chlog("ChatHelper: Major version change from v"+va[0]+"."+va[1]+"."+va[2]+" to v"+vb[0]+"."+vb[1]+"."+vb[2]); } else { if (va[1] != vb[1]){ //minor version change chlog("ChatHelper: Minor version change from v"+va[0]+"."+va[1]+"."+va[2]+" to v"+vb[0]+"."+vb[1]+"."+vb[2]); } else { if (va[2] != vb[2]){ //patch release chlog("ChatHelper: Version Patched from v"+va[0]+"."+va[1]+"."+va[2]+" to v"+vb[0]+"."+vb[1]+"."+vb[2]); } } } } else { //no version change localStorage.getItem('chatHelper'); } saveObj = saveObjTmp; } contacts = saveObj.contacts; saveData(); }catch(err){ chlog(err); } } if (!localStorage.myContacts) { chlog("Deprecated contacts variable does not exist.",1); loadData(); } else { //contacts = loadData(); loadData(); chlog("Contacts: " + contacts, 1); } function saveContact(fr) { chlog("Number of contacts == "+contacts.length,1); contacts.push(fr); chlog(fr + " added to contacts list.",1); saveData(); } function caseInsensitiveSort(a, b) { a = a.toLowerCase(); b = b.toLowerCase(); if (a > b) return 1; if (a < b) return -1; return 0; } function listContacts() { var len = contacts.length; var a = contacts.sort(caseInsensitiveSort); if (len == 1) { alert(len + " Contact:\n\n" + a.join("\n") + "\n"); } else if (len > 1) { alert(len + " Contacts:\n\n" + a.join("\n") + "\n"); } else { var p = prompt("Your contacts list is empty.\n\nType a name here to add a contact:\n", ""); if (p) { saveContact(p); } } } function deleteContact(fr) { if (fr === "all") { contacts = []; chlog("All contacts deleted",1); saveData(); } else { var ind = contacts.indexOf(fr); if (ind > -1) { saveObj.contacts = contacts.splice(ind, 1); saveData(); chlog(contacts,1); chlog(fr + " deleted from contacts list."); } } } function keyUpTimer(kEv) { kEv = kEv || window.event; if (kEv.target.type === "text" && kEv.target.value !== '') { var inputField = kEv.target; var inText = inputField.value; var len = inText.length; var sub; var kc = kEv.keyCode; if (len >= 10 && inText.match(/^(\/whisper)/) !== null) { isWhisp = true; } if (isWhisp && len >= 10 && !kEv.altGraphKey && !kEv.ctrlKey && !kEv.altKey && kc > 47 && kc < 91) { chlog("keyUpTimer keyCode =="+kEv.keyCode,1); sub = inText.substr(9); if (!sub.match(/\s/)) { for (var i = 0; i < contacts.length; i++) { var slen = sub.length; if (contacts[i][slen - 1] === sub[slen - 1] && contacts[i].substr(0, slen) == sub) { inputField.value = "/whisper " + contacts[i] + " "; inputField.setSelectionRange(10 + slen - 1, 10 + contacts[i].length, "forward"); } } } else { isWhisp = false; } } else { isWhisp = false; } } } document.onkeyup = function (kEv) { clearTimeout(timer); timer = setTimeout(function () { keyUpTimer(kEv); }, onkeyupDelay); }; function delayedConfirm() { if (confirm("Add " + _sub + " to your contacts list?\n\nYou can see a list of your contacts by typing /list")) { saveContact(_sub); } } function autoTag(inputField, inText) { // var isUrl = false; // var lookBack; ////auto coords inText = inText.replace(/(\[coords\])*([0-9]{3,4})[:|.]([0-9]{3,4})([:|.]\w+)?(\[\/coords\])*/gi, function(){ var result = new Array(); result.push('[coords]'); result.push(arguments[2]); result.push(':'); result.push(arguments[3]); if(arguments[4] !== undefined) { result.push(arguments[4].replace('.',':')); } result.push('[/coords]'); return result.join(''); }); // shorthand for player ////auto url inText = inText.replace(/(\[url\])*(https?:\/\/)?([\da-z\.-]+)(\.[a-z]{2,6})([\/\w\.\-\=\?\&#]*)*\/?(\[\/url\])*/gi, function(){ var result = new Array(); result.push('[url]'); result.push(arguments[2]); // http[s]:// result.push(arguments[3]); // domain result.push(arguments[4]); // ext result.push(arguments[5]); // query string result.push('[/url]'); return result.join(''); }); inText = inText.replace(/\[p\]([a-z0-9_\-\s]+)\[\/p\]/gi, '[player]$1[/player]'); // shorthand for alliance inText = inText.replace(/\[a\]([a-z0-9_\-\s]+)\[\/a\]/gi, '[alliance]$1[/alliance]'); return inText; } document.onkeydown = function (kEv) { kEv = kEv || window.event; /* Tab key if (kEv.keyCode == 9){ chlog("Tab key pressed",1) var input = qx.core.Init.getApplication().getChat().getChatWidget().getEditable(); // Input kEv.preventDefault(); kEv.stopPropagation(); } */ if (kEv.keyCode === 13) { var inputField = document.querySelector('input:focus, textarea:focus'); var inText = inputField.value; var add = inText.match(/^(\/add)/); var del = inText.match(/^(\/del)/); var showContacts = inText.match(/^((\/contacts)|(\/list))/); var sub; var cf; if (inText.match(/^(\/whisper)/) !== null || add !== null) { if (add !== null) { sub = inText.substr(5); } else { sub = inText.substr(9); } if (sub.match(/^(\w*)\s/)) { //if space after player name (is a whisper or a typo) var arr = sub.match(/^(\w*)/); sub = arr[0].replace(/\s$/, ""); if (contacts.indexOf(sub) == -1) { //not in contacts list _sub = sub; setTimeout(delayedConfirm, 500); } } else if (contacts.indexOf(sub) == -1) { //no message to send, not in contacts, promt to add, clear input chlog("clearing input field",1); inputField.focus(); //?necessary? inputField.value = ""; var cf = confirm("Add " + sub + " to your contacts list?\n\nYou can see a list of your contacts by typing /list"); if (cf) { saveContact(sub); return false; } else { return false; } } else if (sub && contacts.indexOf(sub) > -1) { //not a whisper, reject duplicate contact alert(sub + " is already in your contacts list."); } } //remove contact(s) if (del) { sub = inText.substr(5); chlog("clearing input field",1); inputField.value = ""; if ((contacts.indexOf(sub) > -1 || sub == "all") && confirm("Really delete " + sub + " from your contacts?")) { deleteContact(sub); } else { alert(sub + " is not in your contacts list."); } return false; } // show contacts list if (showContacts) { chlog("clearing input field",1); inputField.value = ""; listContacts(); return false; } // /chelp dialog if (inText.length === 6 && inText.match(/^(\/chelp)/) !== null) { chlog("clearing input field",1); inputField.value = ""; showHelp(); return false; } if (inputField !== null) { chlog("onEnter auto-tagging",1); inText = autoTag(inputField, inText); //auto-tag if (inText !== inputField.value) { inputField.value = inText; } } } if (kEv.altKey && !kEv.shiftKey && !kEv.altGraphKey && !kEv.ctrlKey && kEv.target !== null && (kEv.target.type === "textarea" || kEv.target.type === "text")) { var inputField = kEv.target; var inText = inputField.value; // Alt key, not Ctrl or AltGr if (kEv.altKey && !kEv.altGraphKey && !kEv.ctrlKey) { var cc = kEv.charCode; var kc = kEv.keyCode; chlog("charCode == "+cc,1); chlog("keyCode == "+kc,1); /* Alt+1 for auto Coordinates/Urls in message body */ if (inputField.type === "textarea" && (cc === 49 || kc === 49)) { var pos = getCaretPos(inputField); chlog("attempting Alt+1 message auto-tag",1); if (inputField !== null) { var st = inputField.scrollTop; inText = autoTag(inputField, inText); //auto-tag if (inText !== "" || inText !== inputField.value) { inputField.value = inText; inputField.scrollTop = st; moveCaret(inputField, 0); } } } /* Alt+2 for URLs fallback */ if (cc === 50 || kc === 50) { if (inputField !== null) { var url = prompt("Website (Syntax: google.com or www.google.com)", ""); if (url !== null) { inputField.value += '[url]' + url + '[/url]'; } } } /* Alt+3 or Alt+p for players */ if ((cc === 112 || kc === 80) || (cc === 51 || kc === 51)) { tagWith('[player]', inputField); if (window.chatHelper_suppressBrowserAltKeys) return false; } /* Alt+4 or Alt+a for alliances */ if ((cc === 97 || kc === 65) || (cc === 52 || kc === 52)) { tagWith('[alliance]', inputField); if (window.chatHelper_suppressBrowserAltKeys) return false; } /* Alt+0 to clear tags */ if (cc === 48 || kc === 48) { if (inputField.type === 'textarea') var st = inputField.scrollTop; if (inputField !== null) { inText = inText.replace(/\[\/?coords\]/gi, ''); inText = inText.replace(/\[\/?url\]/gi, ''); inText = inText.replace(/\[\/?player\]/gi, ''); inText = inText.replace(/\[\/?alliance\]/gi, ''); inText = inText.replace(/\[\/?b\]/gi, ''); inText = inText.replace(/\[\/?i\]/gi, ''); inText = inText.replace(/\[\/?u\]/gi, ''); inText = inText.replace(/\[\/?s\]/gi, ''); inputField.value = inText; } if (inputField.type === 'textarea') inputField.scrollTop = st; } /* Alt+b for bold */ if (cc === 98 || kc === 66) { tagWith('[b]', inputField); if (window.chatHelper_suppressBrowserAltKeys) return false; } /* Alt+i for italics */ if (cc === 105 || kc === 73) { tagWith('[i]', inputField); if (window.chatHelper_suppressBrowserAltKeys) return false; } /* Alt+u for underline */ if (cc === 117 || kc === 85) { tagWith('[u]', inputField); if (window.chatHelper_suppressBrowserAltKeys) return false; } /* Alt+s for strikethrough */ if (cc === 115 || kc === 83) { tagWith('[s]', inputField); if (window.chatHelper_suppressBrowserAltKeys) return false; } } } }; } }catch (err) { chlog("createchatHelper: "+ err,1); console.error(err); } function chatHelper_checkIfLoaded() { try { if (typeof qx !== 'undefined') { createchatHelper(); } else { window.setTimeout(chatHelper_checkIfLoaded, 1333); } } catch (err) { console.log("chatHelper_checkIfLoaded: ", err); } } window.setTimeout(chatHelper_checkIfLoaded, 1333); }; try { var chatHelper = document.createElement("script"); chatHelper.innerHTML = "(" + chatHelper_main.toString() + ")();"; chatHelper.type = "text/javascript"; document.getElementsByTagName("head")[0].appendChild(chatHelper); } catch (err) { console.log("chatHelper: init error: ", err); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址