見出し画像

【メモ】WordPressとティラノスクリプトをつなぐアイデアメモ(ドラフト段階)

⚠️⚠️ ※この記事はメモです。コロコロ内容が変わります。 ⚠️⚠️
⚠️ソースは基本的に検証していないので、コピペでは使えねぇっす⚠️

ということで。
ティラノスクリプトで作成したものをWordPressの記事に入れる・・は良く考えられるパターンですが、そうじゃなくてですね。
WordPressのデータをティラクスクリプトに読み込ませたいパターンの方です。何がやりたいかというのは…今の時点ではナイショにしておきます。
この記事は、社内のメンバーに対して「こんな事できそう」を共有するメモ用ですので、内容がくるくる変わります。ご注意ください。

WordPress側

カスタム投稿を準備。
※通常公開する記事とは別に、ティラクスクリプトへ送るためのコンテンツを専用に管理するため。

以下はそのURLのサンプル。REST APIを使ってJSONを吐き出す。

http://example.com/wp-json/wp/v2/posts/(カスタム投稿タイプ名)

カスタム投稿タイプの'public'パラメータをfalseに設定すれば、サイト上からのアクセスを防ぐことができ、REST APIでのみ取得可能となる。

Ajaxを利用

非同期で読み込む場合、プラグインを作って仕込むのはありかな?

function load_posts_by_ajax() {
    // 必要な投稿データを取得する処理をここに記述
    $data = []; // 例として空の配列を用意
    // 応答としてJSONを出力
    wp_send_json_success($data);
}
// ログインユーザー向けのAJAXアクションフック
add_action('wp_ajax_load_posts', 'load_posts_by_ajax');
// 非ログインユーザー向けのAJAXアクションフック
add_action('wp_ajax_nopriv_load_posts', 'load_posts_by_ajax');

エンドポイントの作成

/wp-json/custom/v0/testを作成。

function add_custom_endpoint() {
    register_rest_route(
        'custom/v0', // ネームスペース
        '/test', // ベースURL
        [
            'methods' => WP_REST_Server::READABLE,
            'permission_callback' => '__return_true',
            'callback' => 'fetch_test_data'
        ]
    );
}
add_action('rest_api_init', 'add_custom_endpoint');

WP_REST_Responseを使用してJSON形式で返却

function rest_response($file_name, $param = null) {
    $api_file = locate_template("api/${file_name}.php");
    $res = !empty($api_file) ? include_once $api_file : [];
    $response = new WP_REST_Response($res);
    $response->set_status(200);
    return $response;
}

function fetch_test_data($param) {
    return rest_response('fetch-test-data', $param);
}

ノンス生成

※REST APIを利用してユーザー登録させる場合のCSRFトークン生成。
プラグインに実装。

// functions.php
function enqueue_my_custom_script() {
    wp_enqueue_script('my-custom-script', 'path/to/my-custom-script.js', array('jquery'), null, true);

    // ノンスを生成し、JavaScriptファイルに渡す
    wp_localize_script('my-custom-script', 'myScript', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('my_custom_nonce')
    ));
}
add_action('wp_enqueue_scripts', 'enqueue_my_custom_script');

カスタムフィールドを用意してJSONを書き出す

<?php
// カスタムフィールドを取得
$custom_fields = get_field('your_custom_field_name');

// JSON形式にエンコード
$json_data = json_encode($custom_fields, JSON_UNESCAPED_UNICODE);

// JSONデータを出力
echo $json_data;
?>

セキュアな処理を追加する。

<?php
// ユーザー権限の確認
if (!current_user_can('manage_options')) {
  wp_die('権限がありません');
}

// AJAXリクエストのセキュリティチェック
check_ajax_referer('my_nonce_action', 'nonce');

// カスタムフィールドのデータ取得
$custom_fields = get_post_custom($post_id);

// 必要なデータのみを選択してサニタイズ
$secure_data = array();
foreach ($custom_fields as $key => $value) {
  $secure_data[$key] = sanitize_text_field($value[0]);
}

// JSON形式にエンコードして出力
echo json_encode($secure_data, JSON_UNESCAPED_UNICODE);
exit;
?>

ティラノスクリプト側

プラグインファイルを準備

ソースの基本形は以下で良いのかな?

// WordPressのREST APIからカスタム投稿データを取得する関数
function loadCustomPosts() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'http://example.com/wp-json/wp/v2/posts/(カスタム投稿タイプ名)');
    xhr.onload = function() {
        if (xhr.status === 200) {
            // レスポンスをJSONとしてパース
            var data = JSON.parse(xhr.responseText);
            // データをティラノスクリプトの変数に格納
            tyrano.plugin.kag.variable.tf.custom_posts = data;
            // ここで読み込んだデータを使って何か処理を行う
        } else {
            // エラー処理
            console.error('Failed to load custom posts:', xhr.status);
        }
    };
    xhr.send();
}

// ゲームの初期化時にカスタム投稿データを読み込む
tyrano.plugin.kag.ftag.startTag('first.ks', {
    callback: loadCustomPosts
});

とりあえず、基本形のみメモ。

ティラノスクリプト側でやりたいことのメモ

ティラノスクリプトで位置情報を取得

うーんと、コレでよいのかな…たぶん。あとは処理をゴニョっと…。

// ユーザーの現在の位置情報を取得する
navigator.geolocation.getCurrentPosition(function(position) {
    // 位置情報が取得できた場合の処理
    console.log('Latitude : ' + position.coords.latitude);
    console.log('Longitude: ' + position.coords.longitude);
}, function(error) {
    // 位置情報が取得できなかった場合の処理
    console.error('Error Code = ' + error.code + ' - ' + error.message);
});

ティラクスクリプト側からWordPressへ登録

※注意すること

  • セキュリティ:パスワードなどの機密情報は安全に送信すること。
    クロスサイトスクリプティング(XSS)やクロスサイトリクエストフォージェリ(CSRF)などの攻撃から保護するための対策が必要。

  • 認証:APIリクエストに適切な認証トークンを含める必要がある。

function registerUser(username, password, email) {
    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'http://example.com/wp-json/wp/v2/users');
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    xhr.onload = function() {
        if (xhr.status === 201) {
            // ユーザー登録成功
            var response = JSON.parse(xhr.responseText);
            console.log('User ID:', response.id); // 登録したユーザーのID
        } else {
            // エラー処理
            console.error('User registration failed:', xhr.status);
        }
    };
    xhr.send(JSON.stringify({
        username: username,
        password: password,
        email: email
    }));
}

// 使用例
registerUser('newuser', 'password123', 'user@example.com');

処理部分はこんな感じになるのかな…

// WordPress REST APIエンドポイント
const apiEndpoint = 'http://example.com/wp-json/wp/v2/users/register';

// ユーザー登録データ
const userData = {
    username: 'newuser', // 新しいユーザー名
    password: 'UserPassword123!', // 強力なパスワード
    email: 'user@example.com' // ユーザーのメールアドレス
};

// ユーザー登録関数
function registerUser(userData) {
    fetch(apiEndpoint, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify(userData)
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('User registration failed');
        }
        return response.json();
    })
    .then(data => {
        console.log('User registered successfully:', data);
        // 登録されたユーザーのIDを使用する処理をここに記述
    })
    .catch(error => {
        console.error('Error:', error);
    });
}

// ユーザー登録関数を呼び出す
registerUser(userData);

ちょっとセキュアに…

function registerUser(username, password, email) {
    // 強力なパスワードポリシーをクライアント側で検証する
    if (!isStrongPassword(password)) {
        console.error('Password does not meet the security requirements.');
        return;
    }

    var xhr = new XMLHttpRequest();
    xhr.open('POST', 'https://example.com/wp-json/wp/v2/users'); // HTTPSを使用
    xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
    xhr.setRequestHeader('X-CSRF-Token', '取得したCSRFトークン'); // CSRFトークンを設定

    xhr.onload = function() {
        if (xhr.status === 201) {
            // ユーザー登録成功
            var response = JSON.parse(xhr.responseText);
            console.log('User ID:', response.id); // 登録したユーザーのID
        } else {
            // エラーハンドリングを改善
            console.error('An error occurred during the registration process.');
        }
    };

    xhr.send(JSON.stringify({
        username: username,
        password: password,
        email: email
    }));
}

// 強力なパスワードを検証する関数
function isStrongPassword(password) {
    // パスワードが強力であるかの検証ロジックを実装
    return true; // 仮の実装
}

// 使用例
registerUser('newuser', 'password123', 'user@example.com');

忘れない用に…
CSRFトークンを使った場合のサンプルコード(fetch API利用)

// ユーザー登録を行う関数
function registerUser(username, password, email, nonce) {
    // WordPress REST APIのエンドポイント
    const apiEndpoint = 'https://your-wordpress-site.com/wp-json/wp/v2/users';

    // ユーザー登録データ
    const userData = {
        username: username,
        password: password,
        email: email
    };

    // fetch APIを使用してリクエストを送信
    fetch(apiEndpoint, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
            // WordPressのノンスをヘッダーに追加
            'X-WP-Nonce': nonce
        },
        body: JSON.stringify(userData)
    })
    .then(response => {
        if (!response.ok) {
            throw new Error('User registration failed');
        }
        return response.json();
    })
    .then(data => {
        console.log('User registered successfully:', data);
        // 登録されたユーザーのIDを使用する処理など
    })
    .catch(error => {
        console.error('Error:', error);
    });
}

// ユーザー登録関数を呼び出す例
// ノンスはWordPressから取得した値を使用してください
registerUser('newuser', 'password123', 'user@example.com', 'your-nonce-value');

QRコードから新しいタブが開いてもユーザーの一意性を保つ処理

QRコードリーダーを使用し、QRコードからデータを取得。
そのデータをもとにセッションIDを生成、新しいタブに渡す基本的な流れ。

// QRコードリーダーの初期化
let qrReader = new QRCodeReader();

// QRコードの読み取り
qrReader.decodeFromCamera((error, result) => {
  if (error) {
    console.error(error);
    return;
  }

  // QRコードから取得したデータ
  let qrData = result.data;

  // セッションIDの生成(例:ユーザーIDと現在時刻を組み合わせたハッシュ値)
  let sessionId = generateSessionId(qrData);

  // 新しいタブで開くページのURL
  let newTabUrl = `https://yourwebsite.com?session_id=${sessionId}`;

  // 新しいタブを開く
  window.open(newTabUrl, '_blank');
});

// セッションIDを生成する関数(仮実装)
function generateSessionId(userData) {
  let timestamp = new Date().getTime();
  return `session_${userData}_${timestamp}`;
}

セキュアにするための追加

// HTTPSを使用していることを確認
if (location.protocol !== 'https:') {
  alert('安全な接続ではありません。HTTPSを使用してください。');
  return;
}

// セッションIDの安全な生成
function generateSessionId(userData) {
  // ランダムな文字列を生成する例
  const randomValue = window.crypto.getRandomValues(new Uint32Array(1))[0];
  return `session_${userData}_${randomValue}`;
}

// エラーハンドリングの強化
qrReader.decodeFromCamera((error, result) => {
  if (error) {
    // エラーメッセージの表示
    alert('QRコードの読み取りに失敗しました。カメラのアクセスを許可しているか確認してください。');
    console.error(error);
    return;
  }
  // 以下の処理は同じ...
});

// URLの検証
function validateUrl(url) {
  const pattern = /^(https?:\/\/)?[\w\-_]+(\.[\w\-_]+)+([\w\-.,@?^=%&:/~+#]*[\w\-@?^=%&/~+#])?$/;
  return pattern.test(url);
}

// 新しいタブを開く前にURLを検証
let newTabUrl = `https://yourwebsite.com?session_id=${sessionId}`;
if (validateUrl(newTabUrl)) {
  window.open(newTabUrl, '_blank');
} else {
  alert('無効なURLです。');
}

印刷されたQRコードは改ざんされやすい。そのためデジタルサイネージや、改ざん防止機能を持つQRコードの使用を検討。

※QRCodeReaderは架空のクラス。実装時にはjsQRなど、QRコードリーダーライブラリを使用。

JSONをパージする

カスタムフィールドを読み取ってパージする流れ。

// WordPressから取得したJSONデータのURL
var jsonUrl = 'http://yourwebsite.com/path/to/your/json';

// JSONデータを取得してパースする
fetch(jsonUrl)
  .then(response => response.json())
  .then(data => {
    // データをティラノスクリプトの変数に格納
    tyrano.plugin.kag.variable.tf.dialogue = data.dialogue;
    tyrano.plugin.kag.variable.tf.branch_dialogue = data.branch_dialogue;
    tyrano.plugin.kag.variable.tf.quiz = data.quiz;
    tyrano.plugin.kag.variable.tf.answer = data.answer;

    // ここで取得したデータを使って何か処理を行う
  })
  .catch(error => console.error('Error:', error));


※現時点ではあくまでサンプルコード。(未実験)

ティラノスタジオ箱庭グラフィックの謎

ティラノスタジオで新規プロジェクトを作る時、PRO版には「箱庭グラフィック」があるんですよ。それを選ぶと、左のメニューが少ない状態でスタートします。で、これがどういうことなのか説明がないので困っております。
※解説文はCopilotさんに聞いた回答なので、あっているかどうか不明。

箱庭グラフィックのときのメニュー
ノベルゲームを選んだときのメニュー

edit.stdio.json

左が箱庭グラフィック右がノベル。
左はedit.stdio.jsonが多い

プロジェクトの設定や編集環境に関する情報が記載される。
以下のような内容が含まれる

  • プロジェクトのタイトルや説明

  • 使用するティラノスクリプトのバージョン

  • エディタの設定(フォントサイズ、色テーマなど)

  • プロジェクトに関連するファイルパスの設定

例)プロジェクト名を変更したい場合は、"title": "新しいプロジェクト名" のように記述。
また、エディタの見た目や挙動をカスタマイズするための設定もこのファイルで行う。

hako.ks

左は箱庭グラフィックでhako.ksファイルが多い。
右はノベル。

「hako.ks」ファイルは、箱庭グラフィックモードで使用する3Dオブジェクトやキャラクターの配置に関する情報を記載。

  • 3D空間の初期化

  • オブジェクトやイメージの定義

  • オブジェクトの表示設定(位置、回転、スケールなど)

  • カメラの位置や傾きの設定

例)3D空間に立方体を配置する場合

[3d_box_new name="mybox" width=100 height=100 depth=100 scale=2 color="0x00ff00"]
[3d_show name="mybox"]

例)3D空間にキャラクターのイメージを表示する場合

[3d_image_new name="akane" texture="akane/normal.png" width=400]
[3d_show name="akane" pos="130,-225,535" rot="0,0,0" scale="0.54,0.54,0.54"]

3D空間を作る場合

ティラノスタジオで3D空間を作成する手順

  1. 最初の準備:

    • `Config.tjs` ファイルを開き`use3D=true` を設定。
      3D機能を有効に。

  2. 3D空間の初期化:

    • シナリオファイル(例えば `first.ks`)に `[3d_init]` タグを配置して3D機能を初期化。

  3. オブジェクトの配置:

    • 3D空間に画像を表示する場合は、`[3d_image_new]` と `[3d_show]` タグを使用。

  4. カメラの設定:

    • 3D空間を見るカメラの位置や傾きを `[3d_camera]` タグで設定。

  5. デバッグ機能:

    • 実際の画面で確認しながら座標を取得できる `[3d_debug]` タグを使用して、オブジェクトの配置を調整。



いいなと思ったら応援しよう!