近況報告的な
多分見てる人も居ないだろうけど一応。
試される大地北海道にて大学生はじめました。
それと同時に一人暮らしを始めてコンビニ夜勤こなしながら生活してます
ようやく余裕ができたので勉強がてらエミュ鯖いじったりするかもしれません
ではまた
JS 基本編
はじめに
この記事は8割の憶測と2割の実測で書かれています。英語が読める方は海外のフォーラムにある投稿を読んだほうが良いでしょう。
私は本職の人でも無いのでそういう方から見れば何言ってんだこいつ、と思われるかもしれませんが温かい目で見てください。
間違いを発見した場合コメントで教えてくれると私が喜びます。
あと、多少プログラムの知識がある前提で書いています。
jsの構文等についてはここでは触れませんので適宜他サイトで勉強してください。
とりあえずエミュ鯖で使うjsの基本的な仕様をまとめましたのでご覧ください。
action()は何度でも呼ばれる
function action(mode, type, selection) { cm.sendOk("メッセージ"); }
試しにこのjsを動かしてみてください。
動画を用意しました。
動かすとわかると思いますがOKを押しても同じメッセージが表示されます。
これはOKボタンを押したり、選択肢を選んだりといったアクションをするたびにaction()が呼び出されるためです。
左下のEND CHATを押すとaction()は呼ばれないため会話が終了します。(sendSimple()のみ特殊でaction()が呼び出されます)
ただ処理の途中でcm.dispose()が実行された場合に限っては何らかのアクションがあってもaction()は呼び出されません。
処理はすべて同時に実行される
これもサンプルを用意しました。
function action(mode, type, selection) { cm.sendOk("メッセージ"); cm.gainItem(5220000, 1); }
こちらは実行するとメッセージが出て同時にアイテムが貰えます。
正確には上から順番に実行され、同時では無いのですがsendOk()等でウィンドウを表示させたからと言って動作が一時停止するわけでも無く、普通に最後まで実行されます。
function action(mode, type, selection) { cm.sendOk("メッセージ1"); cm.sendOk("メッセージ2"); }
こちらの場合メッセージ1は表示されますが、メッセージ2はすでにメッセージ1が表示されているため何も起こりません。
言ってしまえばバグの様なものです、action()1回につきsend等のメッセージを表示させる関数は1つだけ実行されるようにしましょう。
start()について
function start() { action(1, 0, 0); } function action(mode, type, selection) { cm.sendOk("メッセージ"); }
上2つのサンプルでは使っていませんがこのようにしてstart関数を書くことで会話がスタートする時action()が呼ばれるのではなくstart()が呼び出されるようになります。
どちらかと言えばこっちが正式な書き方のような気がします。
最初に呼び出されてからはもう呼び出されることはありませんので、会話の最初にする処理(statusの初期化など)が普通書かれます。
ちなみに関数内にcm.dispose()がありstart()1回で処理が終了するものであればaction()を省いでも大丈夫です。
var status = 0; function start() { if(status) { cm.sendOk("メッセージ2"); cm.dispose(); } else { status++; cm.sendNext("メッセージ1"); } }
動かない例。メッセージ1でNEXTを押すとaction()を呼び出そうとするのでエラーが出ます。
一度の処理で2つ以上のsend系が実行されるのは意味がありませんのでsend系はaction関数内に固めて、start関数内にはsend系は使わないのが無難でしょう。
しかし、表示させたいメッセージが2つ程度であれば
function start() { cm.sendNext("メッセージ1"); } function action(mode, type, selection) { cm.sendOk("メッセージ2"); cm.dispose(); }
このように書いても良いかもしれません。
引数は省略できる
function action() { cm.sendOk("メッセージ1"); cm.dispose(); }
エラーも出ずに動いてくれます。
modeのみ使う場合は
function action(mode) {
このようにしても大丈夫です。
ただしsendSimple()等、3つ目の引数(selection)を使う場合は3つとも書かなくてはいけません。
今回は以上です。まとめ方下手なので分かりづらいと思います、すみません。
追記
function action() { cm.dispose(); cm.gainItem(5220000,1); cm.sendOk("メッセージ"); }
cm.dispose()に関してですがこの順番でも最後のsendOk()まで動いちゃいます。
要はdispose()されてようが最後まで実行しちゃうようです。
途中で処理を止めたい場合は
function action() { cm.dispose(); cm.gainItem(5220000,1); return; cm.sendOk("メッセージ"); }
このようにすると最後のsendOk()は実行されません。
JS send,ask系 メモ①
sendOkやsendYesNoなどの関数はそれぞれでmodeやtypeが変わる。(selectionも)
例 cm.sendYesNo()でNoを押した場合 mode=0, type=2となる。
以下それのまとめメモ 普通に関数の一覧としても使える(Maplecrystal v117使用)
関数 | ボタン | mode | type | selection | 説明 |
---|---|---|---|---|---|
cm.askMapSelection(string) | GO | 1 | 17 | 選んだやつ | 次元の扉用。 |
CANCEL | 0 | 17 | -1 | "#0#マップ名1#2#マップ名2"という様に入れる | |
cm.sendNext(string) | Next | 1 | 0 | -1 | Nextボタンのみ |
cm.sendPrev(string) | OK | 1 | 0 | -1 | OKボタンとPREVボタン |
PREV | 0 | 0 | -1 | ||
cm.sendNextPrev(string) | NEXT | 1 | 0 | 1 | NEXTボタンとPREVボタン |
PREV | 0 | 0 | -1 | ||
cm.sendOk(string) | OK | 1 | 0 | -1 | 多分一番よく使うであろうOKボタン |
cm.sendYesNo(string) | YES | 1 | 2 | -1 | 使いたいけど割りと使うのが難しいYesNoボタン |
NO | 0 | 2 | -1 | ||
cm.sendAcceptDecline(string) | ACCEPT | 1 | 15 | -1 | ACCEPTorDECLINE、クエストでよくつかうやつ |
DECLINE | 0 | 15 | -1 | ||
cm.askAcceptDecline(string) | 上と同じ | ||||
cm.askAvatar(string, int[]) | OK | 1 | 9 | 配列内の位置 | 整形のやつ、配列で顔のIDを与える |
CANCEL | 0 | 9 | -1 | ||
LEAVE SHOP | 0 | 9 | -1 | ||
cm.sendSimple(string) | 選択肢(NEXT) | 1 | 5 | 選んだやつ | 選択肢。一番オーソドックスな分岐 |
END CHAT | 0 | 5 | -1 | なんかこれだけENDCHATで動作が終了しない | |
cm.sendStyle(string,int[]) | OK | 1 | 9 | 配列内の位置 | 髪型のやつ、配列で髪型のIDを与える |
CANCEL | 0 | 9 | -1 | ||
LEAVE SHOP | 0 | 9 | -1 | ||
cm.sendGetNumber(string,int(初期値),int(最小),int(最大)) | OK | 1 | 4 | 受け取った数字 | 数字を打たせるやつ。数字じゃないと通らない。負の数はムリ |
cm.sendGetText(string) | OK | 1 | 3 | -1 | テキストを取得、空でも通る。cm.getText()でStringとして受け取れる |
cm.askAndroid(string,int...) | 使用法を調べる気にもならない |
こんなところでしょうか。
statusやmodeだけではなくtypeも組み合わせることでJSの幅が広がります。
また今度JSの仕様についていろいろ書きます。
v117.2 日本語化
いろいろあった結果、バージョンはv117.2で落ち着きました。
MapleCrystalを使用しています。備忘録として日本語表示できるまでを残しておきます。
多分Lithiumベースのリパックならこれでできると思います。
tools.data.MaplePacketLittleEndianWriter.java
- 追加
private static final Charset MS932 = Charset.forName("MS932");
- 変更
変更前
public final void writeAsciiString(final String s) { write(s.getBytes(ASCII)); } public final void writeAsciiString(String s, final int max) { if (s.length() > max) { s = s.substring(0, max); } write(s.getBytes(ASCII)); for (int i = s.length(); i < max; i++) { write(0); } } public final void writeMapleAsciiString(final String s) { writeShort((short) s.length()); writeAsciiString(s); }
変更後
public final void writeAsciiString(final String s) { write(s.getBytes(MS932)); } public final void writeAsciiString(String s, final int max) { if (s.getBytes(MS932).length > max) { s = s.substring(0, max); } write(s.getBytes(MS932)); for (int i = s.getBytes(MS932).length; i < max; i++) { write(0); } } public final void writeMapleAsciiString(final String s) { writeShort((short) s.getBytes(MS932).length); writeAsciiString(s); }
tools.data.LittleEndianAccessor.java
- 変更
変更前
public final String readAsciiString(final int n) { final char ret[] = new char[n]; for (int x = 0; x < n; x++) { ret[x] = (char) readByte(); } return new String(ret); }
変更後
public final String readAsciiString(final int n) { //char ret[] = new char[n]; final byte ret[] = new byte[n]; for (int x = 0; x < n; x++) { ret[x] = (byte) readByte(); } try { String str = new String(ret, "MS932"); return str; } catch (Exception e) { System.err.println(e); } return null; }
tools.StringUtil.java
- 追加
import java.nio.charset.Charset; private static final Charset MS932 = Charset.forName("MS932");
- 変更(RightとLeftで二箇所)
変更前
for (int x = in.length(); x < length; x++) {
変更後
for (int x = in.getBytes(MS932).length; x < length; x++) {
Linux環境では内部の文字コードがutf8なのでgetBytes()としてしまうとMS932とバイト数に差が出るためエラーが起きる。
getBytes(MS932)とすることで解決。
キャラクター名なども問題なく日本語が使えます。
おわり
JCEのインストールとMySQLのインストール
JDKのインストールのときにJCE入れるのを忘れていたのでここで書いておく。
chicken@PiStory:~ $ wget --no-check-certificate --no-cookies --header "Cookie: oraclelicense=accept-securebackup-cookie" http://download.oracle.com/otn-pub/java/jce/8/jce_policy-8.zip chicken@PiStory:~ $ unzip jce_policy-8.zip Archive: jce_policy-8.zip creating: UnlimitedJCEPolicyJDK8/ inflating: UnlimitedJCEPolicyJDK8/local_policy.jar inflating: UnlimitedJCEPolicyJDK8/README.txt inflating: UnlimitedJCEPolicyJDK8/US_export_policy.jar
先程と同じようにDL、解凍。
chicken@PiStory:~ $ cd UnlimitedJCEPolicyJDK8/ chicken@PiStory:~/UnlimitedJCEPolicyJDK8 $ cp US_export_policy.jar local_policy.jar /opt/jdk1.8.0_101/jre/lib/security/
二つのファイルを/opt/jdk1.8.0_101/jre/lib/security/にコピー 他のサイト見てると気が狂ったようにコピーしまくってるが多分この一箇所だけでOK
続いてWZのXMLを置く これも共有フォルダから引っ張ってくる
chicken@PiStory:~ $ cp /mnt/wz.zip wz.zip chicken@PiStory:~ $ unzip wz.zip -d PiStory
MySQLのインストール
chicken@PiStory:~/PiStory $ sudo apt-get install mysql-server
途中でパスワードの設定がある。
文字コードの設定をする
chicken@PiStory:~/PiStory $ sudo vim /etc/mysql/my.cnf [client] default-character-set=utf8 [mysqld] collation-server = utf8_unicode_ci init-connect='SET NAMES utf8' character-set-server = utf8 [mysqldump] default-character-set=utf8
各所に書き足す。
chicken@PiStory:~/PiStory $ sudo /etc/init.d/mysql restart [ ok ] Restarting mysql (via systemctl): mysql.service.
リスタートしてから確認する。
chicken@PiStory:~/PiStory $ mysql -u root -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 37 Server version: 5.5.52-0+deb8u1 (Raspbian) Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> status -------------- mysql Ver 14.14 Distrib 5.5.52, for debian-linux-gnu (armv7l) using readline 6.3 Connection id: 37 Current database: Current user: root@localhost SSL: Not in use Current pager: stdout Using outfile: '' Using delimiter: ; Server version: 5.5.52-0+deb8u1 (Raspbian) Protocol version: 10 Connection: Localhost via UNIX socket Server characterset: utf8 Db characterset: utf8 Client characterset: utf8 Conn. characterset: utf8 UNIX socket: /var/run/mysqld/mysqld.sock Uptime: 6 min 16 sec Threads: 1 Questions: 111 Slow queries: 0 Opens: 48 Flush tables: 1 Open tables: 41 Queries per second avg: 0.295 --------------
mysql>source ~/PiStory/SQL/MoopleDEV.sql mysql>exit
設定いじった後のjarを入れて起動してみる。
chicken@PiStory:~/PiStory $ cp /mnt/MoopleDEV.jar dist/MoopleDEV.jar chicken@PiStory:~/PiStory $ sh launch.sh MoopleDEV v83 starting up. Loading Skills Skills loaded in 5.086 seconds Loading Items Items loaded in 4.672 seconds Listening on port 8484 Server is now online.
成功。やったぜ。 フルクラもないし接続テストはまた明日。
リパック解凍~起動用シェル作成まで
とりあえずリパックを解凍する 今回はv83のMoopleDEVを使う。
ノートPCの共有フォルダを/mnt/にマウントしてあるのでそこからDLしておいたリパックを持ってくる
chicken@PiStory:~ $ cp /mnt/MoopleDEV.zip MoopleDEV.zip
解凍する
chicken@PiStory:~ $ mkdir PiStory chicken@PiStory:~ $ unzip MoopleDEV.zip -d PiStory
とりあえずCreateINIを動かしてみる
chicken@PiStory:~/PiStory $ sh create_server_linux.sh エラー: メイン・クラスnet.server.CreateINIが見つからなかったかロードできませんでした
動かない。
chicken@PiStory:~/PiStory $ java -classpath .:dist/* net.server.CreateINI Welcome to MoopleDEV's .ini creator
こうすると動いた。 INIが作れたので起動用SHを実行してみるが
chicken@PiStory:~/PiStory $ sh launch_server.sh : not founder.sh: 2: launch_server.sh: : bad variable name: export:
まぁ動かない。ので
chicken@PiStory:~/PiStory $ java -classpath .:dist/* -Dwzpath=wz/ -Xmx128m net.server.Server MoopleDEV v83 starting up.
こうした。 もちろんWZも入れてないしMySQLも動いてないのでエラーが大量に出る。 ただ準備はできたので次回はMySQL入れる。(予定)