@jx3box/jx3box-editor 1.4.9 → 1.4.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/GameText.vue +158 -118
- package/src/Item.vue +2 -2
- package/src/Resource.vue +7 -3
package/package.json
CHANGED
package/src/GameText.vue
CHANGED
|
@@ -2,141 +2,181 @@
|
|
|
2
2
|
* @Author: X3ZvaWQ
|
|
3
3
|
* @Date: 2022-08-20 20:23:57
|
|
4
4
|
* @LastEditors: X3ZvaWQ
|
|
5
|
-
* @LastEditTime: 2022-08-
|
|
5
|
+
* @LastEditTime: 2022-08-24 22:32:56
|
|
6
6
|
* @Description: 用于渲染游戏内Text标签的文本
|
|
7
7
|
-->
|
|
8
8
|
<template>
|
|
9
|
-
|
|
9
|
+
<span v-html="html"></span>
|
|
10
10
|
</template>
|
|
11
11
|
|
|
12
12
|
<script>
|
|
13
13
|
import { extractTextContent, getLink } from "@jx3box/jx3box-common/js/utils";
|
|
14
14
|
import { getResource } from "../service/resource";
|
|
15
|
+
import { escape } from "lodash";
|
|
15
16
|
|
|
16
17
|
export default {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
client: {
|
|
24
|
-
type: String,
|
|
25
|
-
default: "std",
|
|
26
|
-
},
|
|
18
|
+
name: "GameText",
|
|
19
|
+
props: {
|
|
20
|
+
text: {
|
|
21
|
+
type: String,
|
|
22
|
+
default: "",
|
|
27
23
|
},
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
};
|
|
24
|
+
client: {
|
|
25
|
+
type: String,
|
|
26
|
+
default: "std",
|
|
32
27
|
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
28
|
+
},
|
|
29
|
+
data: function () {
|
|
30
|
+
return {
|
|
31
|
+
html: "",
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
methods: {
|
|
35
|
+
/**
|
|
36
|
+
* 渲染某一个单独的Text标签成Span或链接
|
|
37
|
+
* @param {*} school_id
|
|
38
|
+
* @returns
|
|
39
|
+
*/
|
|
40
|
+
renderItemHtml: function (item) {
|
|
41
|
+
let content = item.text;
|
|
42
|
+
let style = ``;
|
|
43
|
+
let link = null;
|
|
44
|
+
content = content.replace(/\\n/g, "<br />").replace(/\\/g, "");
|
|
45
|
+
if ([item.r, item.g, item.b].every((v) => v != undefined && v > 0)) {
|
|
46
|
+
style = `color: rgb(${item.r}, ${item.g}, ${item.b});`;
|
|
47
|
+
} else if (item.font != undefined && item.font != 100) {
|
|
48
|
+
const fonts = require("../assets/data/game_font.json");
|
|
49
|
+
for (let color in fonts) {
|
|
50
|
+
if (fonts[color].includes(item.font)) {
|
|
51
|
+
style = `color: ${color};`;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (item.name == "iteminfolink" && item.script) {
|
|
57
|
+
let item_type = item.script?.match(/this\.dwTabType=(\d+)/i)?.[1];
|
|
58
|
+
let item_index = item.script?.match(/this\.dwIndex=(\d+)/i)?.[1];
|
|
59
|
+
if (item_type && item_index) {
|
|
60
|
+
let item_id = `${item_type}_${item_index}`;
|
|
61
|
+
link = getLink("item", item_id);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (link) {
|
|
65
|
+
return `<a style="${style} text-decoration: none;" target="_blank" href="${link}">${content}</a>`;
|
|
66
|
+
} else {
|
|
67
|
+
return `<span style="${style}">${content}</span>`;
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
/**
|
|
71
|
+
* 将一段游戏内文本转换为Html
|
|
72
|
+
* @param {Object[]} texts 标签对象
|
|
73
|
+
*/
|
|
74
|
+
renderTextHtml: function (Text) {
|
|
75
|
+
let result = Text;
|
|
76
|
+
const matches = Text.match(/<Text>(.*?)<\/text>/gimsy);
|
|
77
|
+
if (!matches) return Text;
|
|
78
|
+
for (let match of matches) {
|
|
79
|
+
let text = extractTextContent(match);
|
|
80
|
+
let html = this.renderItemHtml(text[0]);
|
|
81
|
+
result = result.replace(match, html);
|
|
82
|
+
}
|
|
83
|
+
return result;
|
|
84
|
+
},
|
|
85
|
+
/**
|
|
86
|
+
* 获取形如<BUFF 110 1 desc>, <ENCHANT 100>的资源字段并转换
|
|
87
|
+
*/
|
|
88
|
+
renderBuffResource: function () {
|
|
89
|
+
const matches = this.html.match(/<BUFF (\d+) (\d+) (.*?)>/gim);
|
|
90
|
+
if (!matches) return;
|
|
91
|
+
let need_replaces = {};
|
|
92
|
+
//先统计需要的资源,减少请求数量
|
|
93
|
+
for (let match of matches) {
|
|
94
|
+
let [token, id, level, type] = match.match(/<BUFF (\d+) (\d+) (.*?)>/i);
|
|
95
|
+
let buff_token = `${id}_${level}`;
|
|
96
|
+
if (!need_replaces[buff_token]) {
|
|
97
|
+
need_replaces[buff_token] = [];
|
|
98
|
+
}
|
|
99
|
+
need_replaces[buff_token].push({
|
|
100
|
+
token,
|
|
101
|
+
type,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//对每一个需要的资源发起请求
|
|
105
|
+
for (let buff_token in need_replaces) {
|
|
106
|
+
let token_item = need_replaces[buff_token];
|
|
107
|
+
getResource(`buff.${buff_token}`, this.client)
|
|
108
|
+
.then((res) => {
|
|
109
|
+
let data = res.data;
|
|
110
|
+
for (let item of token_item) {
|
|
111
|
+
item.type = item.type.toLowerCase();
|
|
112
|
+
let type_map = {
|
|
113
|
+
desc: "Desc",
|
|
114
|
+
time: "Interval",
|
|
115
|
+
};
|
|
116
|
+
let attr = type_map[item.type] || item.type;
|
|
117
|
+
let value = data[attr];
|
|
118
|
+
if (typeof value == "number" && item.type == "time") {
|
|
119
|
+
let time = value / 16;
|
|
120
|
+
if (time > 60) {
|
|
121
|
+
time = `${Math.floor(time / 60)}分钟`;
|
|
122
|
+
} else {
|
|
123
|
+
time = `${time}秒`;
|
|
53
124
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
125
|
+
this.html = this.html.replace(item.token, time);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
if (!value) return;
|
|
129
|
+
let _matches = value.match(/<BUFF ([0-9a-zA-Z]+)>/gi);
|
|
130
|
+
if (!_matches) this.html = this.html.replace(match, value);
|
|
131
|
+
for (let _match of _matches) {
|
|
132
|
+
let [, _attr] = _match.match(/<BUFF ([0-9a-zA-Z]+)>/i);
|
|
133
|
+
for (let i = 1; i < 15; i++) {
|
|
134
|
+
if (data[`BeginAttrib${i}`] == _attr) {
|
|
135
|
+
value = value.replace(_match, data[`BeginValue${i}A`]);
|
|
136
|
+
}
|
|
61
137
|
}
|
|
138
|
+
}
|
|
139
|
+
this.html = this.html.replace(item.token, value);
|
|
62
140
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let [, id, level, type] = match.match(/<BUFF (\d+) (\d+) (.*?)>/i);
|
|
92
|
-
type = type.toLowerCase();
|
|
93
|
-
let type_map = {
|
|
94
|
-
desc: "Desc",
|
|
95
|
-
time: "Interval",
|
|
96
|
-
};
|
|
97
|
-
getResource(`buff.${id}_${level}`, this.client)
|
|
98
|
-
.then((res) => {
|
|
99
|
-
let data = res.data;
|
|
100
|
-
let attr = type_map[type] || type;
|
|
101
|
-
let value = data[attr];
|
|
102
|
-
if (typeof value == "number" && type == "time") {
|
|
103
|
-
let time = value / 16;
|
|
104
|
-
if (time > 60) {
|
|
105
|
-
time = `${Math.floor(time / 60)}分钟`;
|
|
106
|
-
} else {
|
|
107
|
-
time = `${time}秒`;
|
|
108
|
-
}
|
|
109
|
-
this.html = this.html.replace(match, time);
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
if (!value) return;
|
|
113
|
-
let _matches = value.match(/<BUFF ([0-9a-zA-Z]+)>/gi);
|
|
114
|
-
if (!_matches) this.html = this.html.replace(match, value);
|
|
115
|
-
for (let _match of _matches) {
|
|
116
|
-
let [, _attr] = _match.match(/<BUFF ([0-9a-zA-Z]+)>/i);
|
|
117
|
-
for (let i = 1; i < 15; i++) {
|
|
118
|
-
if (data[`BeginAttrib${i}`] == _attr) {
|
|
119
|
-
value = value.replace(_match, data[`BeginValue${i}A`]);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
this.html = this.html.replace(match, value);
|
|
124
|
-
})
|
|
125
|
-
.catch((err) => {
|
|
126
|
-
console.log(err);
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
},
|
|
141
|
+
})
|
|
142
|
+
.catch((err) => {
|
|
143
|
+
console.log(err);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
renderEnchantResource: function () {
|
|
148
|
+
const matches = this.html.match(/<ENCHANT (\d+)>/gim);
|
|
149
|
+
if(!matches) return;
|
|
150
|
+
for (let match of matches) {
|
|
151
|
+
let enchant_id = match.match(/<ENCHANT (\d+)>/i)[1];
|
|
152
|
+
getResource(`enchant.${enchant_id}`, this.client)
|
|
153
|
+
.then((res) => {
|
|
154
|
+
let data = res.data;
|
|
155
|
+
let time = data.Time;
|
|
156
|
+
if (time) time = `,持续${parseInt(time) / 60}分钟。`;
|
|
157
|
+
let result = `${data.AttriName}${time ? time : ""}`;
|
|
158
|
+
this.html = this.html.replace(match, result);
|
|
159
|
+
})
|
|
160
|
+
.catch((err) => {
|
|
161
|
+
this.html = this.html.replace(match, escape(match));
|
|
162
|
+
console.log(err);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
renderResource: function () {
|
|
167
|
+
this.renderBuffResource();
|
|
168
|
+
this.renderEnchantResource();
|
|
130
169
|
},
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
170
|
+
},
|
|
171
|
+
watch: {
|
|
172
|
+
text: {
|
|
173
|
+
immediate: true,
|
|
174
|
+
handler: function (val) {
|
|
175
|
+
this.html = this.renderTextHtml(val);
|
|
176
|
+
this.renderResource();
|
|
177
|
+
},
|
|
139
178
|
},
|
|
179
|
+
},
|
|
140
180
|
};
|
|
141
181
|
</script>
|
|
142
182
|
|
package/src/Item.vue
CHANGED
|
@@ -176,9 +176,9 @@
|
|
|
176
176
|
</div>
|
|
177
177
|
<!-- 描述 -->
|
|
178
178
|
<p
|
|
179
|
-
v-if="source.
|
|
179
|
+
v-if="source.Desc"
|
|
180
180
|
class="u-desc u-yellow">
|
|
181
|
-
<game-text :client="client" :text="source.
|
|
181
|
+
<game-text :client="client" :text="source.Desc"></game-text>
|
|
182
182
|
</p>
|
|
183
183
|
<!-- 五彩石属性 -->
|
|
184
184
|
<p v-if="source.WuCaiHtml" class="u-desc" v-html="source.WuCaiHtml"></p>
|
package/src/Resource.vue
CHANGED
|
@@ -102,7 +102,9 @@
|
|
|
102
102
|
<span class="u-id">ID:{{ o.id }}</span>
|
|
103
103
|
<img class="u-pic" :title="'IconID:' + o.IconID" :src="iconURL(o.IconID)" />
|
|
104
104
|
<span class="u-name">{{ o.Name }}</span>
|
|
105
|
-
<span class="u-content"
|
|
105
|
+
<span class="u-content">
|
|
106
|
+
<game-text :text="o.Desc"></game-text>
|
|
107
|
+
</span>
|
|
106
108
|
<span class="u-remark">
|
|
107
109
|
{{ o.Requirement }}
|
|
108
110
|
</span>
|
|
@@ -202,6 +204,7 @@ import { loadEmotions } from "../service/cms";
|
|
|
202
204
|
import { __ossRoot, __iconPath, __Root, __OriginRoot } from "@jx3box/jx3box-common/data/jx3box.json";
|
|
203
205
|
import detach_types from "../assets/data/detach_type.json";
|
|
204
206
|
import { iconLink, getLink, showAvatar } from "@jx3box/jx3box-common/js/utils";
|
|
207
|
+
import GameText from "./GameText.vue";
|
|
205
208
|
import User from "@jx3box/jx3box-common/js/user";
|
|
206
209
|
import Item from './Item.vue';
|
|
207
210
|
export default {
|
|
@@ -287,7 +290,7 @@ export default {
|
|
|
287
290
|
},
|
|
288
291
|
canInsertAuthor: function() {
|
|
289
292
|
return User.getLevel(this.userInfo && this.userInfo.experience) >= 2;
|
|
290
|
-
}
|
|
293
|
+
}
|
|
291
294
|
},
|
|
292
295
|
watch: {
|
|
293
296
|
html: function(newval) {
|
|
@@ -502,7 +505,8 @@ export default {
|
|
|
502
505
|
this.checkUA();
|
|
503
506
|
},
|
|
504
507
|
components: {
|
|
505
|
-
'jx3-item': Item
|
|
508
|
+
'jx3-item': Item,
|
|
509
|
+
GameText
|
|
506
510
|
},
|
|
507
511
|
};
|
|
508
512
|
</script>
|