From 27f1a259b57ad4bc82b1fbdce7fb67a5be653a22 Mon Sep 17 00:00:00 2001 From: Freddie Date: Wed, 27 May 2020 18:36:34 +0100 Subject: [PATCH] template release --- README.md | 5 ++++ handlers/example.ts | 53 ++++++++++++++++++++++++++++++++++++++ index.ts | 42 ++++++++++++++++++++++++++++++ templates/example.pug | 5 ++++ templates/example.xml | 7 +++++ webui/css/profile_name.css | 3 +++ webui/custom_page.pug | 29 +++++++++++++++++++++ webui/js/custom_page.js | 5 ++++ webui/profile_name.pug | 42 ++++++++++++++++++++++++++++++ 9 files changed, 191 insertions(+) create mode 100644 README.md create mode 100644 handlers/example.ts create mode 100644 index.ts create mode 100644 templates/example.pug create mode 100644 templates/example.xml create mode 100644 webui/css/profile_name.css create mode 100644 webui/custom_page.pug create mode 100644 webui/js/custom_page.js create mode 100644 webui/profile_name.pug diff --git a/README.md b/README.md new file mode 100644 index 0000000..5c13c69 --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Plugin Template + +This readme file will be shown in WebUI. + +You can follow this example to create your own plugin. diff --git a/handlers/example.ts b/handlers/example.ts new file mode 100644 index 0000000..31b3813 --- /dev/null +++ b/handlers/example.ts @@ -0,0 +1,53 @@ +/* +EamusePluginRoute. Handle your game message like this + +You can send a plain XML request to test this route: + + + +*/ +export const example: EPR = async (info, data, send) => { + /* [Check documentation for the entire API] */ + + /* + Access data from request like this + NOTE: all card number will be automatically converted to refid. + This is to support older game that doesn't use cardmng, + yet still allow them to register with internal profile manager. + And they can show up in WebUI as a profile, along with card binding feature. + */ + const refid = $(data).attr().card; + + /* Access config like this */ + const event = U.GetConfig('event'); + + /* + Create user data in profile space if not exists + WebUI will try to find a "name" field in profile documents and display them. + If you are using a collection of data for each profile, + make sure to avoid using name field in supplementary documents. + If you have multiple documents per refid, it is recommended to provide a field to + simulate collections in NoSQL database (e.g. MongoDB) + */ + await DB.Upsert( + refid, + { + collection: 'profile', + name: 'PLAYER', + }, + { $inc: { login_count: 1 } } + ); + + /* + Send your response like this + There are more methods for sending request. + */ + send.pugFile('templates/example.pug', { refid, event }); + + /* Or you can send ejs template (plain xml works as well) */ + // send.xmlFile('templates/example.xml', { refid, event }); +}; + +export const changeName = async (data: any) => { + await DB.Update(data.refid, { collection: 'profile' }, { $set: { name: data.name } }); +}; diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..d8a7133 --- /dev/null +++ b/index.ts @@ -0,0 +1,42 @@ +import { example, changeName } from './handlers/example'; + +export function register() { + /* Register game code */ + R.GameCode('NULL'); + + /* A plugin can have multiple contributors. */ + R.Contributor('Your Name', 'http://your-link.com'); + R.Contributor('Others Name'); + + /* Register plugin configuration */ + R.Config('event', { + type: 'string', + default: 'EVENT_1', + options: ['EVENT_1', 'EVENT_2'], + }); + + /* Register your routes */ + R.Route('example.method', example); + + /* + Register a unhandled handler that print all unhandled methods. + You should remove it before you publish your plugin, + unless you have specific reason not to. + */ + R.Unhandled(); + + /* Insert or clear a existing document in plugin space */ + DB.Upsert({ clicked: { $exists: true } }, { $set: { clicked: 0 } }); + + /* Register a event and increment the click counter */ + R.WebUIEvent('click', async data => { + console.log('WebUI Button Clicked'); + await DB.Update({ clicked: { $exists: true } }, { $inc: { clicked: 1 } }); + }); + + /* Register a event and increment the click counter */ + R.WebUIEvent('change', changeName); + + /* Use --dev argument to enable console output. */ + console.log('Plugin Registered'); +} diff --git a/templates/example.pug b/templates/example.pug new file mode 100644 index 0000000..38dfe19 --- /dev/null +++ b/templates/example.pug @@ -0,0 +1,5 @@ +//- + Learn pug here: https://pugjs.org/api/getting-started.html +example(status="0") + refid(__type="str") #{refid} + event(__type="str") #{event} \ No newline at end of file diff --git a/templates/example.xml b/templates/example.xml new file mode 100644 index 0000000..264249c --- /dev/null +++ b/templates/example.xml @@ -0,0 +1,7 @@ + + + <%= refid %> + <%= event %> + \ No newline at end of file diff --git a/webui/css/profile_name.css b/webui/css/profile_name.css new file mode 100644 index 0000000..bb2ac1c --- /dev/null +++ b/webui/css/profile_name.css @@ -0,0 +1,3 @@ +#change-name-button { + background-color: rgb(245, 147, 0); +} diff --git a/webui/custom_page.pug b/webui/custom_page.pug new file mode 100644 index 0000000..baa5d1f --- /dev/null +++ b/webui/custom_page.pug @@ -0,0 +1,29 @@ +//- + Custom web component for plugin page + The following frontend components are already avaliable: + * Bulma [https://bulma.io/] + * MaterialDesignIcons [https://materialdesignicons.com/] + * jQuery [https://jquery.com/] + * axios [https://github.com/axios/axios] + * GeoPattern [https://github.com/btmills/geopattern] + * jdenticon [https://jdenticon.com/] + You can include your own js, css or images as well. + + To request data from database, use //DATA// to indicate a comment block for capture and follow: + fieldName: expression + + Then fieldName will be avaliable for the template engine when rendering. + +//DATA// + data: DB.FindOne({ clicked: { $exists: true } }) + +.content + h3 Custom Page + p Clicked: #{data.clicked} + p + button.button.is-primary#plugin-click + | Send "click" event and refresh + +//- You can include custom javascripts and send data back to plugin using emit() + see profile_name.pug for sending data using form +script(src="static/js/custom_page.js") \ No newline at end of file diff --git a/webui/js/custom_page.js b/webui/js/custom_page.js new file mode 100644 index 0000000..86cc11a --- /dev/null +++ b/webui/js/custom_page.js @@ -0,0 +1,5 @@ +$('#plugin-click').on('click', () => { + emit('click', {}).then(() => { + location.reload(); + }); +}); diff --git a/webui/profile_name.pug b/webui/profile_name.pug new file mode 100644 index 0000000..7fd16d4 --- /dev/null +++ b/webui/profile_name.pug @@ -0,0 +1,42 @@ +//- + Custom web component for individual user profile + The following frontend components are already avaliable: + * Bulma [https://bulma.io/] + * MaterialDesignIcons [https://materialdesignicons.com/] + * jQuery [https://jquery.com/] + * axios [https://github.com/axios/axios] + * GeoPattern [https://github.com/btmills/geopattern] + * jdenticon [https://jdenticon.com/] + You can include your own js/css as well + + To request data from database, use //DATA// to indicate a comment block for capture and follow: + fieldName: expression + + Then fieldName will be avaliable for the template engine when rendering. + + WebUI file with prefix "profile_" is different from other pug file: + * This page have a "refid" local variable, you can request data with it or use it during render. + * User can access these page by editing a profile. + +//DATA// + profile: DB.FindOne(refid, { login_count: { $exists: true } }) + +//- + You can include your own stylesheet +link(rel="stylesheet" href="static/css/profile_name.css") + +div + h3 Hi #{profile.name} + + section.section + //- + You can send data back to plugin using post method in form + see custom_page.pug for sending data using emit() function + form(method="post" action="/emit/change") + input(type="hidden" name="refid" value=refid) + .field + label.label Change Name + .field + input.input(type="text" name="name", value=profile.name) + .field + button.button.is-primary#change-name-button(type="submit") Submit