Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6282445f7d | ||
|
|
bf244533f7 | ||
|
|
5ebfaf24ee | ||
|
|
0c0283dc02 | ||
|
|
375b08be87 | ||
|
|
cbc8f94b0a | ||
|
|
bdac8d163d | ||
|
|
1f61f37841 | ||
|
|
51d523ae72 | ||
|
|
3f9e4962e6 | ||
|
|
f8fc4fe56b | ||
|
|
fb64b7e412 | ||
|
|
3209cfbc45 | ||
|
|
8a99476136 | ||
|
|
eb80f8d111 | ||
|
|
afde3ce54d | ||
|
|
c4b61fec17 | ||
|
|
0b74abf300 | ||
|
|
e6c3c9f1d4 | ||
|
|
4e7560b4ed | ||
|
|
542491b278 | ||
|
|
d36439355d | ||
|
|
4a80815b39 | ||
|
|
6dc57f2566 | ||
|
|
07e8511ce1 | ||
|
|
8e927831f5 | ||
|
|
2c533d2ab3 | ||
|
|
38208750e7 | ||
|
|
df14d7c306 | ||
|
|
b3612db7d2 | ||
|
|
8d90da659e | ||
|
|
f8ddbc0622 | ||
|
|
673b7054aa | ||
|
|
1472cbf257 | ||
|
|
d806935c58 | ||
|
|
6b56eb79e1 | ||
|
|
d2aea16744 | ||
|
|
bb800f032e | ||
|
|
64b9f9443e | ||
|
|
fd2d3a0e06 | ||
|
|
08d678bdb8 | ||
|
|
418007e572 | ||
|
|
4a1bccdf75 | ||
|
|
00c0b59e9d | ||
|
|
ac82c8ff0b | ||
|
|
f4bef8a090 | ||
|
|
d8a1055bff | ||
|
|
d672ce4d80 | ||
|
|
43ec361d03 | ||
|
|
c3c99c5f76 | ||
|
|
eb1e1421ab | ||
|
|
e8a1d87919 | ||
|
|
921ba6811d | ||
|
|
906dd241b4 | ||
|
|
3f0cd2ad64 | ||
|
|
41420d1954 | ||
|
|
6e5a72b170 | ||
|
|
4b19e6aec8 | ||
|
|
58572cbc36 | ||
|
|
096d5766bf | ||
|
|
f5c5b56492 | ||
|
|
69c69d63e6 | ||
|
|
3fd8b21867 | ||
|
|
8660e8cd85 | ||
|
|
8458f725f2 | ||
|
|
366678c965 | ||
|
|
336b5668db | ||
|
|
55886269ea | ||
|
|
0b3698595b | ||
|
|
05e43a39db | ||
|
|
5737ad3db2 | ||
|
|
4ac174eb9a | ||
|
|
895eec10b4 | ||
|
|
e0d891e89a | ||
|
|
adf7734b85 | ||
|
|
5362be9c21 | ||
|
|
847ece52f2 | ||
|
|
851c59d22c | ||
|
|
0669534bba | ||
|
|
05db47e62a | ||
|
|
4a0e608d1c | ||
|
|
45fe73af86 | ||
|
|
4d9fcd657f | ||
|
|
a057deb0fe | ||
|
|
4766210a7d | ||
|
|
fd26aae6d3 | ||
|
|
c5c092cc8e | ||
|
|
58c0a21d90 | ||
|
|
8dc567f966 | ||
|
|
942b2752f5 | ||
|
|
b9259353f4 | ||
|
|
86c614dd40 | ||
|
|
1a010a16a9 | ||
|
|
d5b5726b1e | ||
|
|
d06f3b6bdf | ||
|
|
97a28f716c | ||
|
|
f54bdfcea0 | ||
|
|
5958c4b0ba | ||
|
|
7c3db881c7 | ||
|
|
51ee2e1b2c | ||
|
|
baa813004b | ||
|
|
86b5269d3d | ||
|
|
860e6dacac | ||
|
|
22025bd89e | ||
|
|
ed9301455d | ||
|
|
35df84e059 | ||
|
|
62deebf310 | ||
|
|
7ed4bd5c01 | ||
|
|
c8eb9332b4 | ||
|
|
1df55f9168 | ||
|
|
b726c6aa96 | ||
|
|
0a71962652 | ||
|
|
160946ef74 | ||
|
|
1dc67317dc | ||
|
|
08f4a2e8bf | ||
|
|
11ffdaa8f7 | ||
|
|
0f853303a4 | ||
|
|
d225eb9b16 | ||
|
|
d926e4b8bc | ||
|
|
3e2df1d4d8 | ||
|
|
d670dbf081 | ||
|
|
f510a312e3 | ||
|
|
19c44e3d31 | ||
|
|
d0848aee67 | ||
|
|
f4b4b6811c | ||
|
|
fecb3f1f7b | ||
|
|
4c924c0763 | ||
|
|
f1e8d70554 | ||
|
|
7d11bc152e | ||
|
|
fdf0a3135a | ||
|
|
3a1a455c48 | ||
|
|
3a786e835b | ||
|
|
c70181132f | ||
|
|
538615a1f5 | ||
|
|
aa20a60a1c | ||
|
|
69fa1dac6c | ||
|
|
3ab349af6e | ||
|
|
97ac7deb2f | ||
|
|
3230cafb9f | ||
|
|
394284d8de | ||
|
|
6323b174c6 | ||
|
|
3d3e0e5139 | ||
|
|
ffc7d4bacc | ||
|
|
598236a1d2 | ||
|
|
69207519bd | ||
|
|
022eb1012f | ||
|
|
0a9c59f91e | ||
|
|
7ebb22b892 | ||
|
|
3dc7fc6f14 | ||
|
|
90dea7517b | ||
|
|
eae48f9564 | ||
|
|
dd7afba5f5 | ||
|
|
73357b6777 | ||
|
|
53df6bbcc6 | ||
|
|
9871559227 | ||
|
|
9cbead1ddc | ||
|
|
6402028c17 | ||
|
|
76bd65cf53 | ||
|
|
6e4113de11 | ||
|
|
12f37f76c7 | ||
|
|
acd77b2c0a | ||
|
|
f4fb4ec00d | ||
|
|
46ae4669ea | ||
|
|
67b2dbfe98 | ||
|
|
4f3b39fbfa | ||
|
|
a28fc52309 | ||
|
|
d5f0d60794 | ||
|
|
72e65587df | ||
|
|
b4d4d90784 | ||
|
|
3f81fb759d | ||
|
|
d995b39e02 | ||
|
|
3bd09a1aa4 | ||
|
|
a6ff951c98 | ||
|
|
604b1557e8 | ||
|
|
279bd5c71a | ||
|
|
97dfb02ab6 | ||
|
|
32c7b02303 | ||
|
|
e135835e61 | ||
|
|
7ed9a8075c | ||
|
|
ead8110fb4 | ||
|
|
586b1b6c15 | ||
|
|
e1727c8d80 | ||
|
|
7bd8a7ff35 | ||
|
|
de48651ae7 | ||
|
|
9902e07be0 | ||
|
|
5e4b38895e | ||
|
|
38bbbf261a | ||
|
|
def0a52578 | ||
|
|
4f1f87bda0 | ||
|
|
15f9faa2fa | ||
|
|
7257491d8b | ||
|
|
c19b2a9ebe | ||
|
|
54e7fd0293 | ||
|
|
21f3a2082b | ||
|
|
f647eb5a7b | ||
|
|
d7b1db0081 | ||
|
|
11511316d1 | ||
|
|
95a93c2c44 | ||
|
|
815ce10c25 | ||
|
|
5f13bfe8a1 | ||
|
|
5cd494c00a | ||
|
|
5a0a8bedc1 | ||
|
|
3b9884160b | ||
|
|
5b2b01328a | ||
|
|
e5b51dcd16 | ||
|
|
4d8b816acf | ||
|
|
fa109c1b0b | ||
|
|
b987fce627 | ||
|
|
b072cc3266 | ||
|
|
366b40ea90 | ||
|
|
3d3daa205d | ||
|
|
665ebbd11a | ||
|
|
52a5a7697d | ||
|
|
97a38d516a | ||
|
|
e89475bf52 | ||
|
|
90a78b05ce | ||
|
|
8c6eff15f0 | ||
|
|
824c58b391 | ||
|
|
b97500430c | ||
|
|
bacafc67c9 | ||
|
|
f23ebcdc2d | ||
|
|
edbe8e3561 | ||
|
|
05d1e33b30 | ||
|
|
96b60ce0f5 | ||
|
|
6174bc7ffd | ||
|
|
3bd022e03a | ||
|
|
b0cc5b0b60 | ||
|
|
5493f70458 | ||
|
|
323b3d9d16 | ||
|
|
1b0742ad2a | ||
|
|
2eb7217f49 | ||
|
|
b6f5a286b0 | ||
|
|
66c496fb10 | ||
|
|
56ca588c1e | ||
|
|
e2b09caff3 | ||
|
|
a5b4a4c59f | ||
|
|
a70312a90a | ||
|
|
6c6a3238cb | ||
|
|
9af10d4bcb | ||
|
|
f6e1b4611e | ||
|
|
7bc762d357 | ||
|
|
8edf1da92b | ||
|
|
a18baf2ffe | ||
|
|
2d41bf8f2f | ||
|
|
334778bdae | ||
|
|
1b46a06eee | ||
|
|
1e860e9443 | ||
|
|
0b973672d2 | ||
|
|
868ed85c7f | ||
|
|
6f2a24ec66 | ||
|
|
e5d5899a15 | ||
|
|
243473a97d | ||
|
|
28d71b8ce2 | ||
|
|
1acbf90261 | ||
|
|
94229f84a3 | ||
|
|
cead74238a | ||
|
|
73c60ea94c | ||
|
|
73638da4db | ||
|
|
bc218b73e1 | ||
|
|
aac6632f4b | ||
|
|
fdba3fdc74 | ||
|
|
21bb61ec82 | ||
|
|
ce1203d64d | ||
|
|
56daf15c8e | ||
|
|
96faa924d8 | ||
|
|
ee8854451c | ||
|
|
0975e925a9 | ||
|
|
83d6a2169b | ||
|
|
21e7a4d966 | ||
|
|
404cd24855 | ||
|
|
b4ad72ee67 | ||
|
|
bea628b619 | ||
|
|
3637e54982 | ||
|
|
e0d1a0a612 | ||
|
|
3040996671 | ||
|
|
dd830e7500 | ||
|
|
d2dfe2c418 | ||
|
|
139fb6b6e0 | ||
|
|
c4f6976c42 | ||
|
|
ab428fc104 | ||
|
|
aa97f78acd | ||
|
|
dbce900aeb | ||
|
|
30b382e2e7 | ||
|
|
433c4abb86 | ||
|
|
64404e4092 | ||
|
|
08d483af8a | ||
|
|
fa19c17941 | ||
|
|
c896a999ad | ||
|
|
f9bca935ac | ||
|
|
7abf274d89 | ||
|
|
e2ad417306 | ||
|
|
2ea9655f6b | ||
|
|
f450d5d9de | ||
|
|
f8f4b73a09 | ||
|
|
926d96732d | ||
|
|
167113d6a3 | ||
|
|
911cb614a5 | ||
|
|
7a939b7024 | ||
|
|
6e57a60997 | ||
|
|
9f1151e699 | ||
|
|
3fbe1fb63d | ||
|
|
d4906eec5a | ||
|
|
ebe0663e74 | ||
|
|
04c89b9711 | ||
|
|
4f2bc874e5 | ||
|
|
316ac5c3c8 | ||
|
|
7882aa667e | ||
|
|
8b8d5eecbf | ||
|
|
65b76643ee | ||
|
|
f33e645113 | ||
|
|
528d30c317 | ||
|
|
7f0a3d320c | ||
|
|
8e940aeb65 | ||
|
|
a77ee60809 | ||
|
|
83383c29cd | ||
|
|
b6393141e8 | ||
|
|
10ce1827d8 | ||
|
|
605f3a12ff | ||
|
|
a33539e75f | ||
|
|
b2cca3687a | ||
|
|
628c54044f | ||
|
|
c0e7a3eece | ||
|
|
c7c13c19c1 | ||
|
|
d5f71b5878 | ||
|
|
cb589e9e26 | ||
|
|
eaeed47297 | ||
|
|
e00e5c5cd7 | ||
|
|
b3719f7166 | ||
|
|
337896974b | ||
|
|
bb7d1fc9ab | ||
|
|
07765c8d44 | ||
|
|
85cb91071e | ||
|
|
d41839845a | ||
|
|
c3d12aa55f | ||
|
|
a781e4b84c | ||
|
|
1fc0989fd2 | ||
|
|
14752260d3 | ||
|
|
84675c874f | ||
|
|
f30e6057be | ||
|
|
ba8b629f0e | ||
|
|
a0a45ff2aa | ||
|
|
325f890a0b | ||
|
|
923cac5408 | ||
|
|
23505326c7 | ||
|
|
5f1a48f523 | ||
|
|
a607d39030 | ||
|
|
96d108729e | ||
|
|
ef15adaaf8 | ||
|
|
f190b74a7e | ||
|
|
edbc2b88b6 | ||
|
|
dc000cecf1 | ||
|
|
7c95a483df | ||
|
|
27e5d73da1 | ||
|
|
6306dae92d | ||
|
|
a427ddff83 | ||
|
|
b62ee6e820 | ||
|
|
3c18666080 | ||
|
|
40968b301a | ||
|
|
05904d31fd | ||
|
|
75aeaf4ee7 | ||
|
|
ff4e67a9f6 | ||
|
|
5f672d5bd1 | ||
|
|
5cb39eba8b | ||
|
|
4d8c3c75d6 | ||
|
|
8bdd19fc06 | ||
|
|
0ec99d8ba1 | ||
|
|
929d2db5a5 | ||
|
|
a7ad77f433 | ||
|
|
9cd47d5deb | ||
|
|
3cb5691aae | ||
|
|
dce63919fa | ||
|
|
1cdbedcb96 | ||
|
|
1586712ce5 | ||
|
|
f059186494 | ||
|
|
0af0be57b0 | ||
|
|
dad2b03212 | ||
|
|
b6e307660f | ||
|
|
c21c14825a | ||
|
|
39f9c986e9 | ||
|
|
393683aebc | ||
|
|
a87fcb44a6 | ||
|
|
0a6496ddfb | ||
|
|
fa2841fac6 | ||
|
|
861e45419b | ||
|
|
15fd943456 | ||
|
|
b538bfc27e | ||
|
|
e0f32eddc4 | ||
|
|
75a704c196 | ||
|
|
6565fdbe7e | ||
|
|
6248d72852 | ||
|
|
00d1797b96 | ||
|
|
911194eba8 | ||
|
|
0fad3ae31d | ||
|
|
b6988d866a | ||
|
|
e30959a656 | ||
|
|
52eeff3466 | ||
|
|
a06ded552d | ||
|
|
e9b8a84243 | ||
|
|
1fc3cfd1f2 |
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"useBuiltIns": "usage",
|
||||
"corejs": 3,
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
],
|
||||
"plugins": [
|
||||
"lodash"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: "vue-eslint-parser",
|
||||
parserOptions: {
|
||||
"project": "./tsconfig.json"
|
||||
},
|
||||
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'webpack.config.cjs', '*.js'],
|
||||
overrides: [{
|
||||
files: ['*.ts', '*.tsx', "*.vue"],
|
||||
}],
|
||||
plugins: [
|
||||
"@typescript-eslint",
|
||||
|
||||
],
|
||||
extends: [
|
||||
"eslint:recommended",
|
||||
'plugin:vue/essential',
|
||||
'@vue/typescript',
|
||||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended"
|
||||
],
|
||||
rules: {
|
||||
'@typescript-eslint/no-floating-promises': 'error',
|
||||
"vue/no-multiple-template-root": "off",
|
||||
"vue/no-v-for-template-key": "off",
|
||||
}
|
||||
}
|
||||
+67
-50
@@ -1,50 +1,67 @@
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
|
||||
|
||||
|
||||
# 체섭 ignore
|
||||
*.log
|
||||
|
||||
logs/*.txt
|
||||
d_log/*.txt
|
||||
d_log/*.zip
|
||||
sess_*
|
||||
*/logs/*.txt
|
||||
*/logs/*/*.txt
|
||||
*/logs/preserved
|
||||
err.txt
|
||||
che/.htaccess
|
||||
kwe/.htaccess
|
||||
pwe/.htaccess
|
||||
twe/.htaccess
|
||||
hwe/.htaccess
|
||||
|
||||
d_shared
|
||||
|
||||
d_pic/*.jpg
|
||||
d_pic/*.gif
|
||||
d_pic/*.png
|
||||
d_pic/uploaded_image
|
||||
|
||||
d_setting/*.php
|
||||
*/d_setting/*.php
|
||||
*/d_setting/templates/*.php
|
||||
|
||||
**/old/*
|
||||
test.php
|
||||
|
||||
/che
|
||||
/kwe
|
||||
/pwe
|
||||
/nya
|
||||
/pya
|
||||
/twe
|
||||
|
||||
phpinfo.php
|
||||
vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/*
|
||||
*.sqlite3
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
|
||||
/node_modules
|
||||
package-lock.json
|
||||
|
||||
|
||||
# 체섭 ignore
|
||||
*.log
|
||||
|
||||
logs/*.txt
|
||||
d_log/*.txt
|
||||
d_log/*.zip
|
||||
sess_*
|
||||
*/logs/*.txt
|
||||
*/logs/*/*.txt
|
||||
*/logs/preserved
|
||||
err.txt
|
||||
che/.htaccess
|
||||
kwe/.htaccess
|
||||
pwe/.htaccess
|
||||
twe/.htaccess
|
||||
hwe/.htaccess
|
||||
|
||||
d_shared
|
||||
|
||||
d_pic/*.jpg
|
||||
d_pic/*.gif
|
||||
d_pic/*.png
|
||||
d_pic/*.webp
|
||||
d_pic/uploaded_image
|
||||
|
||||
*/dist_misc/*
|
||||
*/dist_js/*
|
||||
*/dist_css/*
|
||||
/dist_misc/*
|
||||
/dist_js/*
|
||||
/dist_css/*
|
||||
|
||||
d_setting/*.php
|
||||
*/d_setting/*.php
|
||||
*/d_setting/templates/*.php
|
||||
!*.orig.php
|
||||
|
||||
*/data/file_cache
|
||||
|
||||
**/old/*
|
||||
test.php
|
||||
|
||||
/che
|
||||
/kwe
|
||||
/pwe
|
||||
/nya
|
||||
/pya
|
||||
/twe
|
||||
|
||||
phpinfo.php
|
||||
vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/*
|
||||
*.sqlite3
|
||||
|
||||
ingame/js/*
|
||||
ingame/css/*
|
||||
gateway/js/*
|
||||
gateway/css/*
|
||||
|
||||
+46
-30
@@ -7,7 +7,7 @@
|
||||
*/
|
||||
return [
|
||||
// Supported values: `'5.6'`, `'7.0'`, `'7.1'`, `'7.2'`, `'7.3'`,
|
||||
// `'7.4'`, `null`.
|
||||
// `'7.4'`, `'8.0'`, `'8.1'`, `null`.
|
||||
// If this is set to `null`,
|
||||
// then Phan assumes the PHP version which is closest to the minor version
|
||||
// of the php executable used to execute Phan.
|
||||
@@ -15,21 +15,34 @@ return [
|
||||
// Note that the **only** effect of choosing `'5.6'` is to infer
|
||||
// that functions removed in php 7.0 exist.
|
||||
// (See `backward_compatibility_checks` for additional options)
|
||||
"target_php_version" => '7.3',
|
||||
'backward_compatibility_checks ' => false,
|
||||
'minimum_severity'=>\Phan\Issue::SEVERITY_NORMAL,
|
||||
"target_php_version" => '8.0',
|
||||
'backward_compatibility_checks ' => true,
|
||||
'minimum_severity' => \Phan\Issue::SEVERITY_NORMAL,
|
||||
|
||||
'file_list' => [
|
||||
'f_config/config.php',
|
||||
'hwe/_119_b.php',
|
||||
'hwe/_119.php',
|
||||
'hwe/a_bestGeneral.php',
|
||||
'hwe/a_emperior.php',
|
||||
'hwe/a_emperior2.php',
|
||||
'hwe/_admin1.php',
|
||||
'hwe/_admin1_submit.php',
|
||||
'hwe/_admin2.php',
|
||||
'hwe/_admin2_submit.php',
|
||||
'hwe/_admin4.php',
|
||||
'hwe/_admin4_submit.php',
|
||||
'hwe/_admin5.php',
|
||||
'hwe/_admin5_submit.php',
|
||||
'hwe/_admin7.php',
|
||||
'hwe/_admin8.php',
|
||||
'hwe/_admin_force_rehall.php',
|
||||
'hwe/a_emperior_detail.php',
|
||||
'hwe/a_emperior.php',
|
||||
'hwe/a_genList.php',
|
||||
'hwe/a_hallOfFame.php',
|
||||
'hwe/a_history.php',
|
||||
'hwe/a_kingdomList.php',
|
||||
'hwe/a_npcList.php',
|
||||
'hwe/api.php',
|
||||
'hwe/a_status.php',
|
||||
'hwe/a_traffic.php',
|
||||
'hwe/a_vote.php',
|
||||
@@ -54,7 +67,6 @@ return [
|
||||
'hwe/c_dipcenter.php',
|
||||
'hwe/c_tournament.php',
|
||||
'hwe/c_vote.php',
|
||||
'hwe/func.php',
|
||||
'hwe/func_auction.php',
|
||||
'hwe/func_command.php',
|
||||
'hwe/func_converter.php',
|
||||
@@ -63,16 +75,15 @@ return [
|
||||
'hwe/func_legacy.php',
|
||||
'hwe/func_map.php',
|
||||
'hwe/func_message.php',
|
||||
'hwe/func.php',
|
||||
'hwe/func_process.php',
|
||||
'hwe/func_string.php',
|
||||
'hwe/func_template.php',
|
||||
'hwe/func_time_event.php',
|
||||
'hwe/func_tournament.php',
|
||||
'hwe/index.php',
|
||||
'hwe/install.php',
|
||||
'hwe/install_db.php',
|
||||
'hwe/join.php',
|
||||
'hwe/join_post.php',
|
||||
'hwe/install.php',
|
||||
'hwe/j_adjust_icon.php',
|
||||
'hwe/j_autoreset.php',
|
||||
'hwe/j_basic_info.php',
|
||||
@@ -87,20 +98,25 @@ return [
|
||||
'hwe/j_diplomacy_respond_letter.php',
|
||||
'hwe/j_diplomacy_rollback_letter.php',
|
||||
'hwe/j_diplomacy_send_letter.php',
|
||||
'hwe/j_export_simulator_object.php',
|
||||
'hwe/j_general_log_old.php',
|
||||
'hwe/j_general_set_permission.php',
|
||||
'hwe/j_general_turn.php',
|
||||
'hwe/j_get_basic_general_list.php',
|
||||
'hwe/j_getChiefTurn.php',
|
||||
'hwe/j_get_city_list.php',
|
||||
'hwe/j_get_general_list.php',
|
||||
'hwe/j_get_nation_general_list.php',
|
||||
'hwe/j_get_reserved_command.php',
|
||||
'hwe/j_get_select_npc_token.php',
|
||||
'hwe/j_get_select_pool.php',
|
||||
'hwe/j_image_upload.php',
|
||||
'hwe/j_install.php',
|
||||
'hwe/j_install_db.php',
|
||||
'hwe/j_install.php',
|
||||
'hwe/j_load_scenarios.php',
|
||||
'hwe/j_map.php',
|
||||
'hwe/j_map_history.php',
|
||||
'hwe/j_map.php',
|
||||
'hwe/j_map_recent.php',
|
||||
'hwe/j_msg_contact_list.php',
|
||||
'hwe/j_msg_decide_opt.php',
|
||||
'hwe/j_msg_delete.php',
|
||||
@@ -108,31 +124,30 @@ return [
|
||||
'hwe/j_msg_get_recent.php',
|
||||
'hwe/j_msg_submit.php',
|
||||
'hwe/j_myBossInfo.php',
|
||||
'hwe/j_raise_event.php',
|
||||
'hwe/j_select_npc.php',
|
||||
'hwe/j_select_picked_general.php',
|
||||
'hwe/j_server_basic_info.php',
|
||||
'hwe/j_set_chief_command.php',
|
||||
'hwe/j_set_general_command.php',
|
||||
'hwe/j_set_my_setting.php',
|
||||
'hwe/j_set_npc_control.php',
|
||||
'hwe/j_simulate_battle.php',
|
||||
'hwe/j_troop.php',
|
||||
'hwe/j_update_picked_general.php',
|
||||
'hwe/j_vacation.php',
|
||||
'hwe/lib.php',
|
||||
'hwe/process_war.php',
|
||||
'hwe/proc.php',
|
||||
'hwe/readme.php',
|
||||
'hwe/recent_map.php',
|
||||
'hwe/select_general_from_pool.php',
|
||||
'hwe/select_npc.php',
|
||||
'hwe/t_board.php',
|
||||
'hwe/t_diplomacy.php',
|
||||
'hwe/_119.php',
|
||||
'hwe/_119_b.php',
|
||||
'hwe/_admin1.php',
|
||||
'hwe/_admin1_submit.php',
|
||||
'hwe/_admin2.php',
|
||||
'hwe/_admin2_submit.php',
|
||||
'hwe/_admin4.php',
|
||||
'hwe/_admin4_submit.php',
|
||||
'hwe/_admin5.php',
|
||||
'hwe/_admin5_submit.php',
|
||||
'hwe/_admin7.php',
|
||||
'hwe/_admin8.php',
|
||||
'hwe/_admin_force_rehall.php',
|
||||
'hwe/v_board.php',
|
||||
'hwe/v_inheritPoint.php',
|
||||
'hwe/v_join.php',
|
||||
'hwe/v_NPCControl.php',
|
||||
],
|
||||
|
||||
// A list of directories that should be parsed for class and
|
||||
@@ -143,9 +158,9 @@ return [
|
||||
// Thus, both first-party and third-party code being used by
|
||||
// your application should be included in this list.
|
||||
'directory_list' => [
|
||||
'hwe/d_setting',
|
||||
'hwe/sammo',
|
||||
'd_setting',
|
||||
'hwe/d_setting',
|
||||
'hwe/sammo',
|
||||
'd_setting',
|
||||
'src/sammo',
|
||||
'src/kakao',
|
||||
'vendor'
|
||||
@@ -169,6 +184,7 @@ return [
|
||||
|
||||
'suppress_issue_types' => [
|
||||
'PhanUnreferencedUseNormal',
|
||||
'PhanTypeArraySuspiciousNullable',
|
||||
],
|
||||
|
||||
// A list of plugin files to execute.
|
||||
@@ -185,4 +201,4 @@ return [
|
||||
'PregRegexCheckerPlugin',
|
||||
'PrintfCheckerPlugin',
|
||||
],
|
||||
];
|
||||
];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<title>닫혀 있습니다.</title>
|
||||
<script>
|
||||
setTimeout(function(){
|
||||
window.location = window.location+'/../';
|
||||
window.location.href = '../';
|
||||
}, 5000);
|
||||
</script>
|
||||
<style>
|
||||
@@ -13,7 +13,7 @@
|
||||
background-color:black;
|
||||
color:yellow;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
The MIT License
|
||||
|
||||
Copyright (c) 2020 Hide_D, 62che
|
||||
Copyright (c) 2021 Hide_D, 62che
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -5,22 +5,24 @@
|
||||
|
||||
## 요구사항
|
||||
|
||||
* Apache2
|
||||
* <code>mpm_event</code> 권장
|
||||
* PHP 7.3 이상
|
||||
* <code>php-fpm</code> 권장
|
||||
* php에서 curl, pdo-sqlite을 실행가능해야 합니다. (기본값: 지원)
|
||||
* mysqlnd가 지원되어야합니다. (기본값: 지원)
|
||||
* mysqli
|
||||
* Apache2 또는 nginx
|
||||
* Apache2인 경우 `mpm_event` 권장
|
||||
* PHP 8.0 이상
|
||||
* `php-fpm` 권장
|
||||
* php에서 curl, pdo-sqlite을 실행가능해야 합니다.
|
||||
* mysqli, mysqlnd
|
||||
* gd
|
||||
* mbstring
|
||||
* NodeJS 14 이상
|
||||
* 내부의 git을 통해 upgrade 때 `webpack build` 용도로 필요합니다.
|
||||
* MariaDB 10.2.1 이상
|
||||
* 현재 MySQL은 지원하지 않습니다.
|
||||
* <code>git</code>
|
||||
* <code>curl</code>
|
||||
* `git`
|
||||
* `curl`
|
||||
|
||||
Linux는 Ubuntu 16.04, 18.04, Windows는 Windows 10에서 XAMPP를 사용한 환경에서 테스트되었습니다.
|
||||
Linux는 Ubuntu 18.04, 20.04, Windows는 WSL2를 사용한 환경에서 테스트되었습니다.
|
||||
|
||||
Docker를 이용한 설치는 계획중입니다.
|
||||
Docker를 이용한 설치도 제공하고 있습니다.
|
||||
|
||||
## Docker를 이용한 설치
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
require(__DIR__ . '/vendor/autoload.php');
|
||||
|
||||
|
||||
if (!class_exists('\\sammo\\RootDB')) {
|
||||
Json::dieWithReason('No DB');
|
||||
}
|
||||
|
||||
APIHelper::launch(dirname(__FILE__));
|
||||
+7
-5
@@ -8,7 +8,7 @@
|
||||
],
|
||||
"config": {
|
||||
"platform": {
|
||||
"php": "7.3"
|
||||
"php": "8.0"
|
||||
}
|
||||
},
|
||||
"require": {
|
||||
@@ -16,7 +16,6 @@
|
||||
"sergeytsalkov/meekrodb": "^2.3",
|
||||
"league/plates": "^3.3",
|
||||
"guzzlehttp/guzzle": "^6.3",
|
||||
"scssphp/scssphp": "^1.0",
|
||||
"monolog/monolog": "^1.23",
|
||||
"firephp/firephp-core": "^0.4.0",
|
||||
"vlucas/valitron": "^1.4",
|
||||
@@ -26,8 +25,11 @@
|
||||
"ezyang/htmlpurifier": "^4.10",
|
||||
"xemlock/htmlpurifier-html5": "^0.1.7",
|
||||
"catfan/medoo": "^1.5",
|
||||
"phan/phan": "^2.7",
|
||||
"erusev/parsedown-extra": "^0.8.1"
|
||||
"phan/phan": "*",
|
||||
"erusev/parsedown-extra": "^0.8.1",
|
||||
"nette/caching": "^3.0",
|
||||
"illuminate/database": "^8.61",
|
||||
"illuminate/events": "^8.61"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
@@ -48,5 +50,5 @@
|
||||
"f_config/config.php"
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Generated
+2395
-331
File diff suppressed because it is too large
Load Diff
Regular → Executable
BIN
Binary file not shown.
+240
-181
@@ -1,182 +1,241 @@
|
||||
@charset "utf-8";
|
||||
|
||||
body {
|
||||
color:white; background-color:black; font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
table {
|
||||
border: solid 1px; border-spacing: 0px; border-collapse: separate; border-top-color: gray; border-left-color: gray; border-right-color: black; border-bottom-color: black;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
th, td {
|
||||
border: solid 1px; border-spacing: 0px; border-collapse: separate; border-top-color: gray; border-left-color: gray; border-right-color: black; border-bottom-color: black;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
a.just_link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.with_border{
|
||||
margin:0;
|
||||
border: solid 1px;
|
||||
border-spacing: 0px;
|
||||
border-collapse: separate;
|
||||
border-top-color: gray;
|
||||
border-left-color: gray;
|
||||
border-right-color: black;
|
||||
border-bottom-color: black;
|
||||
}
|
||||
|
||||
.section_title {
|
||||
height:50px;
|
||||
line-height:50px;
|
||||
font-size: 30px; font-weight: bold;
|
||||
text-align: center;
|
||||
color:white;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
.legacy_layout div {
|
||||
border: solid 1px; border-spacing: 0px; border-collapse: separate; border-top-color: gray; border-left-color: gray; border-right-color: black; border-bottom-color: black;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
font-family: '맑은 고딕';;
|
||||
}
|
||||
|
||||
.obj_fill{
|
||||
display:block;
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
button.with_skin {
|
||||
padding:0 4px;
|
||||
background-color: black; color: white;
|
||||
font-family: '맑은 고딕';
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
button.with_skin:disabled {
|
||||
background-color:#333333;
|
||||
}
|
||||
|
||||
input.with_skin {
|
||||
background-color: black; color: white;
|
||||
font-family: '맑은 고딕';
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
input.with_skin:disabled {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.font0 { font-size: 10px; }
|
||||
.font1 { font-size: 13px; }
|
||||
.font2 { font-size: 15px; }
|
||||
.font3 { font-size: 20px; }
|
||||
.font4 { font-size: 30px; }
|
||||
.font5 { font-size: 50px; }
|
||||
|
||||
caption.section_title {
|
||||
caption-side:top;
|
||||
}
|
||||
|
||||
|
||||
.samButton{
|
||||
float:left;
|
||||
display:block;
|
||||
padding:0;
|
||||
margin:0;
|
||||
text-decoration: none;
|
||||
position:relative;
|
||||
}
|
||||
|
||||
a.samButton.disabled {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.samButtonOuter{
|
||||
display: table;
|
||||
border: outset 2px white;
|
||||
box-sizing: border-box;
|
||||
font-weight:bold;
|
||||
padding: 1px 6px;
|
||||
width:125px;
|
||||
height:30px;
|
||||
background-color:#000000;
|
||||
color:#ffffff;
|
||||
}
|
||||
|
||||
.samButtonOuter:active{
|
||||
border: inset 2px white;
|
||||
}
|
||||
|
||||
|
||||
.samButtonInner{
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.samToolbarButton > .samButtonOuter{
|
||||
width:125px;
|
||||
height:30px;
|
||||
background-color:#225500;
|
||||
color:white;
|
||||
}
|
||||
|
||||
.samToolbarButton2 > .samButtonOuter{
|
||||
width:125px;
|
||||
height:30px;
|
||||
background-color:#225500;
|
||||
color:magenta;
|
||||
}
|
||||
|
||||
.samCommandButton > .samButtonOuter{
|
||||
width:111px;
|
||||
height:30px;
|
||||
}
|
||||
|
||||
.samCommandButton.disabled > .samButtonOuter{
|
||||
background-color:transparent !important;
|
||||
color:gray !important;
|
||||
border-color:transparent !important;
|
||||
}
|
||||
|
||||
.samCommandButton.disabled > .samButtonOuter > .samButtonInner::before{
|
||||
content:'【'
|
||||
}
|
||||
|
||||
.samCommandButton.disabled > .samButtonOuter > .samButtonInner::after{
|
||||
content:'】'
|
||||
}
|
||||
|
||||
.tooltip_copyable_info .tooltiptext{
|
||||
display: inline;
|
||||
color: rgba(0,0,0,0);
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.tooltiptext {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hidden_but_copyable{
|
||||
color: rgba(0,0,0,0);
|
||||
font-size: 0;
|
||||
@charset "utf-8";
|
||||
body {
|
||||
color: white;
|
||||
background-color: black;
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
table {
|
||||
border: solid 1px;
|
||||
border-spacing: 0px;
|
||||
border-collapse: separate;
|
||||
border-top-color: gray;
|
||||
border-left-color: gray;
|
||||
border-right-color: black;
|
||||
border-bottom-color: black;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
th,
|
||||
td {
|
||||
border: solid 1px;
|
||||
border-spacing: 0px;
|
||||
border-collapse: separate;
|
||||
border-top-color: gray;
|
||||
border-left-color: gray;
|
||||
border-right-color: black;
|
||||
border-bottom-color: black;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
a.just_link {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.with_border {
|
||||
margin: 0;
|
||||
border: solid 1px;
|
||||
border-spacing: 0px;
|
||||
border-collapse: separate;
|
||||
border-top-color: gray;
|
||||
border-left-color: gray;
|
||||
border-right-color: black;
|
||||
border-bottom-color: black;
|
||||
}
|
||||
|
||||
.section_title {
|
||||
height: 50px;
|
||||
line-height: 50px;
|
||||
font-size: 30px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
color: white;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.legacy_layout div {
|
||||
border: solid 1px;
|
||||
border-spacing: 0px;
|
||||
border-collapse: separate;
|
||||
border-top-color: gray;
|
||||
border-left-color: gray;
|
||||
border-right-color: black;
|
||||
border-bottom-color: black;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
word-break: break-all;
|
||||
text-align: center;
|
||||
font-family: '맑은 고딕';
|
||||
;
|
||||
}
|
||||
|
||||
.obj_fill {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
button.with_skin {
|
||||
padding: 0 4px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-family: '맑은 고딕';
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
button.with_skin:disabled {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
input.with_skin {
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-family: '맑은 고딕';
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
input.with_skin:disabled {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.font0 {
|
||||
font-size: 10px;
|
||||
}
|
||||
|
||||
.font1 {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.font2 {
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.font3 {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.font4 {
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.font5 {
|
||||
font-size: 50px;
|
||||
}
|
||||
|
||||
caption.section_title {
|
||||
caption-side: top;
|
||||
}
|
||||
|
||||
.samButton {
|
||||
float: left;
|
||||
display: block;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
a.samButton.disabled {
|
||||
pointer-events: none;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.samButtonOuter {
|
||||
display: table;
|
||||
border: outset 2px white;
|
||||
box-sizing: border-box;
|
||||
font-weight: bold;
|
||||
padding: 1px 6px;
|
||||
width: 125px;
|
||||
height: 30px;
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.samButtonOuter:active {
|
||||
border: inset 2px white;
|
||||
}
|
||||
|
||||
.samButtonInner {
|
||||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
text-align: center;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.samToolbarButton>.samButtonOuter {
|
||||
width: 125px;
|
||||
height: 30px;
|
||||
background-color: #225500;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.samToolbarButton2>.samButtonOuter {
|
||||
width: 125px;
|
||||
height: 30px;
|
||||
background-color: #225500;
|
||||
color: magenta;
|
||||
}
|
||||
|
||||
.samCommandButton>.samButtonOuter {
|
||||
width: 111px;
|
||||
height: 30px;
|
||||
}
|
||||
|
||||
.samCommandButton.disabled>.samButtonOuter {
|
||||
background-color: transparent !important;
|
||||
color: gray !important;
|
||||
border-color: transparent !important;
|
||||
}
|
||||
|
||||
.samCommandButton.disabled>.samButtonOuter>.samButtonInner::before {
|
||||
content: '【'
|
||||
}
|
||||
|
||||
.samCommandButton.disabled>.samButtonOuter>.samButtonInner::after {
|
||||
content: '】'
|
||||
}
|
||||
|
||||
.tooltip_copyable_info .tooltiptext {
|
||||
display: inline;
|
||||
color: rgba(0, 0, 0, 0);
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.tooltiptext {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hidden_but_copyable {
|
||||
color: rgba(0, 0, 0, 0);
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.vertical_flex {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.vertical_flex .item {
|
||||
display: block;
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
.fill_box {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
+155
-140
@@ -1,141 +1,156 @@
|
||||
@charset "utf-8";
|
||||
|
||||
body{
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
#server_notice {
|
||||
margin:10px 0;
|
||||
border: none;
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
#server_list_container{
|
||||
width:800px;
|
||||
position:absolute;
|
||||
left:50%;
|
||||
margin-left:-400px;
|
||||
}
|
||||
|
||||
#server_list_table{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
#server_list tr{
|
||||
height:66px;
|
||||
}
|
||||
|
||||
#server_list .server_create_and_select .general_create,
|
||||
#server_list .server_create_and_select .general_select {
|
||||
width: 120px; height: 33px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#server_list .general_create,
|
||||
#server_list .general_login {
|
||||
width: 120px; height: 66px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.ignore_border{
|
||||
border:0;
|
||||
margin:0;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
#user_info {
|
||||
margin-top:20px;
|
||||
width: 800px; height: 130px;
|
||||
}
|
||||
|
||||
|
||||
#user_info button{
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 10px 50px;
|
||||
}
|
||||
|
||||
.center_ordered_items{
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.Entrance_ServerList {
|
||||
width: 800px; height: 64px;
|
||||
border: none;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListServer {
|
||||
width: 98px; height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListDown {
|
||||
width: 698px; height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListInfo {
|
||||
width: 398px; height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListBlock {
|
||||
width: 298px; height: 64px;
|
||||
float: left;
|
||||
line-height: 64px;
|
||||
}
|
||||
|
||||
.Entrance_ServerListCharacter {
|
||||
width: 64px; height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListName {
|
||||
width: 112px; height: 64px;
|
||||
float: left;
|
||||
line-height: 64px;
|
||||
}
|
||||
|
||||
|
||||
.Entrance_ServerListSelect {
|
||||
width: 120px; height: 32px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#Entrance_000003 {
|
||||
width: 798px; height: 155px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.Entrance_Alert {
|
||||
color: red; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Che {
|
||||
color: white; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Kwe {
|
||||
color: yellow; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Pwe {
|
||||
color: orange; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Twe {
|
||||
color: magenta; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Nya {
|
||||
color: #e67e22; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Pya {
|
||||
color: #9b59b6; font-size: 15px; font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Hwe {
|
||||
color: red; font-size: 15px; font-weight: bold;
|
||||
@charset "utf-8";
|
||||
body {
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
#server_notice {
|
||||
margin: 10px 0;
|
||||
border: none;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#server_list_container {
|
||||
width: 800px;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -400px;
|
||||
}
|
||||
|
||||
#server_list_table {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#server_list tr {
|
||||
height: 66px;
|
||||
}
|
||||
|
||||
.ignore_border {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#user_info {
|
||||
margin-top: 20px;
|
||||
width: 800px;
|
||||
height: 130px;
|
||||
}
|
||||
|
||||
#user_info button {
|
||||
width: 200px;
|
||||
height: 50px;
|
||||
margin: 10px 50px;
|
||||
}
|
||||
|
||||
.center_ordered_items {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.Entrance_ServerList {
|
||||
width: 800px;
|
||||
height: 64px;
|
||||
border: none;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListServer {
|
||||
width: 98px;
|
||||
height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListDown {
|
||||
width: 698px;
|
||||
height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListInfo {
|
||||
width: 398px;
|
||||
height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListBlock {
|
||||
width: 298px;
|
||||
height: 64px;
|
||||
float: left;
|
||||
line-height: 64px;
|
||||
}
|
||||
|
||||
.Entrance_ServerListCharacter {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
.Entrance_ServerListName {
|
||||
width: 112px;
|
||||
height: 64px;
|
||||
float: left;
|
||||
line-height: 64px;
|
||||
}
|
||||
|
||||
.Entrance_ServerListSelect {
|
||||
width: 120px;
|
||||
height: 32px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
#Entrance_000003 {
|
||||
width: 798px;
|
||||
height: 155px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.Entrance_Alert {
|
||||
color: red;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Che {
|
||||
color: white;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Kwe {
|
||||
color: yellow;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Pwe {
|
||||
color: orange;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Twe {
|
||||
color: magenta;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Nya {
|
||||
color: #e67e22;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Pya {
|
||||
color: #9b59b6;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.Entrance_Hwe {
|
||||
color: red;
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.BtnPlate {
|
||||
height: inherit;
|
||||
}
|
||||
+200
-130
@@ -1,131 +1,201 @@
|
||||
body, html{
|
||||
height: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.main{
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
h1.title {
|
||||
font-size: 50px;
|
||||
font-family: 'Passion One', cursive;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
hr{
|
||||
width: 10%;
|
||||
/*color: #fff;*/
|
||||
}
|
||||
|
||||
.form-group{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
label{
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
input,
|
||||
input::-webkit-input-placeholder {
|
||||
font-size: 11px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.main-login{
|
||||
/*background-color: #fff;*/
|
||||
/* shadows and rounded borders */
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
|
||||
}
|
||||
|
||||
.main-center{
|
||||
margin-top: 30px;
|
||||
margin: 0 auto;
|
||||
max-width: 330px;
|
||||
padding: 40px 40px;
|
||||
|
||||
}
|
||||
|
||||
.login_btn_group{
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.login-register{
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.col-form-label{
|
||||
text-align:center;
|
||||
}
|
||||
|
||||
.terms{
|
||||
max-height: 200px; overflow-y: auto;
|
||||
}
|
||||
|
||||
.terms pre{
|
||||
width:100%;
|
||||
white-space: pre-wrap; /* Since CSS 2.1 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
}
|
||||
|
||||
.vertical-center {
|
||||
min-height: 100%; /* Fallback for browsers do NOT support vh unit */
|
||||
min-height: 100vh; /* These two lines are counted as one :-) */
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.full-content {
|
||||
position:fixed;
|
||||
left:0;
|
||||
top:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
margin:0;
|
||||
padding:0;
|
||||
z-index:800;
|
||||
}
|
||||
|
||||
#login_card{
|
||||
z-index:801;
|
||||
}
|
||||
|
||||
#btn_kakao_login{
|
||||
cursor: pointer;
|
||||
height:46px;
|
||||
width:116px;
|
||||
background-color: transparent;
|
||||
color:transparent;
|
||||
border:0;
|
||||
background-size: 100%; /* To fill the dimensions of container (button), or */
|
||||
background-repeat: no-repeat;
|
||||
background-position: bottom center;
|
||||
margin-top:5px;
|
||||
background-image:url('../oauth_kakao/kakao_login_join.png');
|
||||
}
|
||||
|
||||
#btn_kakao_login:hover {
|
||||
background-image:url('../oauth_kakao/kakao_login_join_ov.png');
|
||||
}
|
||||
|
||||
#bottom_box{
|
||||
position:fixed;
|
||||
bottom:0;
|
||||
width:100%;
|
||||
left:0;
|
||||
}
|
||||
#bottom_box .container{
|
||||
text-align:center;
|
||||
body,
|
||||
html {
|
||||
height: 100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.main {
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
h1.title {
|
||||
font-size: 50px;
|
||||
font-family: 'Passion One', cursive;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
hr {
|
||||
width: 10%;
|
||||
/*color: #fff;*/
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
label {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
input,
|
||||
input::-webkit-input-placeholder {
|
||||
font-size: 11px;
|
||||
padding-top: 3px;
|
||||
}
|
||||
|
||||
.main-login {
|
||||
/*background-color: #fff;*/
|
||||
/* shadows and rounded borders */
|
||||
-moz-border-radius: 2px;
|
||||
-webkit-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.main-center {
|
||||
margin-top: 30px;
|
||||
margin: 0 auto;
|
||||
max-width: 330px;
|
||||
padding: 40px 40px;
|
||||
}
|
||||
|
||||
.login_btn_group {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.login-register {
|
||||
font-size: 11px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.col-form-label {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.terms {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.terms pre {
|
||||
width: 100%;
|
||||
white-space: pre-wrap;
|
||||
/* Since CSS 2.1 */
|
||||
white-space: -moz-pre-wrap;
|
||||
/* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap;
|
||||
/* Opera 4-6 */
|
||||
white-space: -o-pre-wrap;
|
||||
/* Opera 7 */
|
||||
word-wrap: break-word;
|
||||
/* Internet Explorer 5.5+ */
|
||||
}
|
||||
|
||||
.vertical-center {
|
||||
min-height: 100%;
|
||||
/* Fallback for browsers do NOT support vh unit */
|
||||
min-height: 100vh;
|
||||
/* These two lines are counted as one :-) */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#login_card {
|
||||
z-index: 801;
|
||||
}
|
||||
|
||||
#btn_kakao_login {
|
||||
cursor: pointer;
|
||||
height: 46px;
|
||||
width: 116px;
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
border: 0;
|
||||
background-size: 100%;
|
||||
/* To fill the dimensions of container (button), or */
|
||||
background-repeat: no-repeat;
|
||||
background-position: bottom center;
|
||||
margin-top: 5px;
|
||||
background-image: url('../oauth_kakao/kakao_login_join.png');
|
||||
}
|
||||
|
||||
#btn_kakao_login:hover {
|
||||
background-image: url('../oauth_kakao/kakao_login_join_ov.png');
|
||||
}
|
||||
|
||||
#bottom_box .container {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.btn-group-xs>.btn,
|
||||
.btn-xs {
|
||||
padding: .25rem .4rem;
|
||||
font-size: .875rem;
|
||||
line-height: .5;
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
#running_map {
|
||||
border: none;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
|
||||
#map-subframe {
|
||||
display: none;
|
||||
width: 700px;
|
||||
}
|
||||
|
||||
@media only screen and (min-width : 360px) {
|
||||
#map-subframe {
|
||||
display: block;
|
||||
transform: scale(calc(330 / 700));
|
||||
transform-origin: 350px 0px;
|
||||
margin-bottom: -400px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (min-width : 440px) {
|
||||
#map-subframe {
|
||||
transform: scale(calc(410 / 700));
|
||||
margin-bottom: -300px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width : 480px) {
|
||||
#map-subframe {
|
||||
transform: scale(calc(450 / 700));
|
||||
margin-bottom: -250px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (min-width : 520px) {
|
||||
#map-subframe {
|
||||
transform: scale(calc(490 / 700));
|
||||
margin-bottom: -200px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width : 576px) {
|
||||
#map-subframe {
|
||||
transform: scale(calc(546 / 700));
|
||||
margin-bottom: -150px;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (min-width : 640px) {
|
||||
#map-subframe {
|
||||
transform: scale(calc(600/700));
|
||||
margin-bottom: -100px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (min-width : 700px) {
|
||||
#map-subframe {
|
||||
transform: scale(calc(670 / 700));
|
||||
margin-bottom: -20px;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media only screen and (min-width : 730px) {
|
||||
#map-subframe {
|
||||
transform: none;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
Vendored
+3
-3
File diff suppressed because one or more lines are too long
+42
-17
@@ -15,35 +15,35 @@ ini_set("session.gc_maxlifetime", '604800'); // seconds
|
||||
function getFriendlyErrorType($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case E_ERROR: // 1 //
|
||||
case E_ERROR: // 1 //
|
||||
return 'E_ERROR';
|
||||
case E_WARNING: // 2 //
|
||||
case E_WARNING: // 2 //
|
||||
return 'E_WARNING';
|
||||
case E_PARSE: // 4 //
|
||||
case E_PARSE: // 4 //
|
||||
return 'E_PARSE';
|
||||
case E_NOTICE: // 8 //
|
||||
case E_NOTICE: // 8 //
|
||||
return 'E_NOTICE';
|
||||
case E_CORE_ERROR: // 16 //
|
||||
case E_CORE_ERROR: // 16 //
|
||||
return 'E_CORE_ERROR';
|
||||
case E_CORE_WARNING: // 32 //
|
||||
case E_CORE_WARNING: // 32 //
|
||||
return 'E_CORE_WARNING';
|
||||
case E_COMPILE_ERROR: // 64 //
|
||||
case E_COMPILE_ERROR: // 64 //
|
||||
return 'E_COMPILE_ERROR';
|
||||
case E_COMPILE_WARNING: // 128 //
|
||||
case E_COMPILE_WARNING: // 128 //
|
||||
return 'E_COMPILE_WARNING';
|
||||
case E_USER_ERROR: // 256 //
|
||||
case E_USER_ERROR: // 256 //
|
||||
return 'E_USER_ERROR';
|
||||
case E_USER_WARNING: // 512 //
|
||||
case E_USER_WARNING: // 512 //
|
||||
return 'E_USER_WARNING';
|
||||
case E_USER_NOTICE: // 1024 //
|
||||
case E_USER_NOTICE: // 1024 //
|
||||
return 'E_USER_NOTICE';
|
||||
case E_STRICT: // 2048 //
|
||||
case E_STRICT: // 2048 //
|
||||
return 'E_STRICT';
|
||||
case E_RECOVERABLE_ERROR: // 4096 //
|
||||
case E_RECOVERABLE_ERROR: // 4096 //
|
||||
return 'E_RECOVERABLE_ERROR';
|
||||
case E_DEPRECATED: // 8192 //
|
||||
case E_DEPRECATED: // 8192 //
|
||||
return 'E_DEPRECATED';
|
||||
case E_USER_DEPRECATED: // 16384 //
|
||||
case E_USER_DEPRECATED: // 16384 //
|
||||
return 'E_USER_DEPRECATED';
|
||||
}
|
||||
return "{$type}";
|
||||
@@ -117,7 +117,7 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
|
||||
]);
|
||||
}
|
||||
|
||||
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext)
|
||||
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext=null)
|
||||
{
|
||||
if (!(error_reporting() & $errno)) {
|
||||
// This error code is not included in error_reporting, so let it fall
|
||||
@@ -134,7 +134,7 @@ function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, in
|
||||
getExceptionTraceAsString($e)
|
||||
);
|
||||
}
|
||||
set_error_handler("\sammo\logErrorByCustomHandler");
|
||||
set_error_handler("\\sammo\\logErrorByCustomHandler");
|
||||
|
||||
|
||||
function logExceptionByCustomHandler(\Throwable $e)
|
||||
@@ -151,3 +151,28 @@ function logExceptionByCustomHandler(\Throwable $e)
|
||||
throw $e;
|
||||
}
|
||||
set_exception_handler('\\sammo\\logExceptionByCustomHandler');
|
||||
|
||||
function getAPIExecutorClass($path){
|
||||
|
||||
static $basePath = __NAMESPACE__.'\\API\\';
|
||||
if(is_string($path)){
|
||||
}
|
||||
else if(is_array($path)){
|
||||
$path = join('\\', $path);
|
||||
}
|
||||
else{
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
|
||||
}
|
||||
|
||||
$classPath = str_replace('/', '\\', $basePath.$path);
|
||||
|
||||
if(class_exists($classPath)){
|
||||
return $classPath;
|
||||
}
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
|
||||
}
|
||||
|
||||
function buildAPIExecutorClass($type, string $rootPath, array $args):\sammo\BaseAPI{
|
||||
$class = getAPIExecutorClass($type);
|
||||
return new $class($rootPath, $args);
|
||||
}
|
||||
+22
-25
@@ -11,12 +11,9 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>설치</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery.validate.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/sha512.min.js')?>
|
||||
<?=WebUtil::printJS('../js/common.js')?>
|
||||
<?=WebUtil::printJS('../js/install.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||
<?=WebUtil::printJS('../dist_js/vendors.js') ?>
|
||||
<?=WebUtil::printJS('../dist_js/install.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../css/install.css')?>
|
||||
</head>
|
||||
@@ -29,13 +26,13 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="card" id="db_form_card" style="display:none">
|
||||
<h3 class="card-header">
|
||||
설치(DB 설정)
|
||||
</h3>
|
||||
</h3>
|
||||
<div class="card-body">
|
||||
<form id="db_form" method="post" action="#">
|
||||
<div class="form-group row">
|
||||
<label for="db_host" class="col-sm-4 col-form-label">DB호스트</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="db_host" id="db_host"
|
||||
<input type="text" class="form-control" name="db_host" id="db_host"
|
||||
placeholder="호스트" value="localhost" />
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,11 +40,11 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="db_port" class="col-sm-4 col-form-label">DB포트</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="db_port" id="db_port"
|
||||
<input type="text" class="form-control" name="db_port" id="db_port"
|
||||
placeholder="접속 포트" value="3306" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="db_id" class="col-sm-4 col-form-label">DB계정명</label>
|
||||
<div class="col-sm-8">
|
||||
@@ -55,11 +52,11 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="db_pw" class="col-sm-4 col-form-label">DB비밀번호</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="password" class="form-control" name="db_pw" id="db_pw"
|
||||
<input type="password" class="form-control" name="db_pw" id="db_pw"
|
||||
placeholder="DB비밀번호"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -67,7 +64,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="db_name" class="col-sm-4 col-form-label">DB명</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="db_name" id="db_name"
|
||||
<input type="text" class="form-control" name="db_name" id="db_name"
|
||||
placeholder="DB명(예:sammo)"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -75,7 +72,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="serv_host" class="col-sm-4 col-form-label">접속 경로</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="serv_host" id="serv_host"
|
||||
<input type="text" class="form-control" name="serv_host" id="serv_host"
|
||||
placeholder="접속경로(예:http://www.example.com)"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -83,7 +80,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="shared_icon_path" class="col-sm-4 col-form-label">공용 아이콘 주소</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="shared_icon_path" id="shared_icon_path"
|
||||
<input type="text" class="form-control" name="shared_icon_path" id="shared_icon_path"
|
||||
placeholder="공용 아이콘 주소(웹 주소, 또는 접속 경로에 따른 상대 주소)"
|
||||
value="../image/icons" />
|
||||
</div>
|
||||
@@ -92,7 +89,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="game_image_path" class="col-sm-4 col-form-label">게임 이미지 주소</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="game_image_path" id="game_image_path"
|
||||
<input type="text" class="form-control" name="game_image_path" id="game_image_path"
|
||||
placeholder="게임 이미지 주소(웹 주소, 또는 접속 경로에 따른 상대 주소)"
|
||||
value="../image/game" />
|
||||
</div>
|
||||
@@ -101,7 +98,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="image_request_key" class="col-sm-4 col-form-label">이미지 갱신 키</label>
|
||||
<div class="input-group col-sm-8">
|
||||
<input type="text" class="form-control" name="image_request_key" id="image_request_key"
|
||||
<input type="text" class="form-control" name="image_request_key" id="image_request_key"
|
||||
placeholder="이미지 서버의 hook/HashKey.php의 값과 동일하게"
|
||||
value="" />
|
||||
<div class="input-group-append">
|
||||
@@ -115,7 +112,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="kakao_rest_key" class="col-sm-4 col-form-label">카카오 API Rest Key</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="kakao_rest_key" id="kakao_rest_key"
|
||||
<input type="text" class="form-control" name="kakao_rest_key" id="kakao_rest_key"
|
||||
placeholder="카카오톡 API의 Rest Key"
|
||||
value="" />
|
||||
</div>
|
||||
@@ -124,7 +121,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="kakao_admin_key" class="col-sm-4 col-form-label">카카오 API Admin Key</label>
|
||||
<div class="col-sm-8">
|
||||
<input type="text" class="form-control" name="kakao_admin_key" id="kakao_admin_key"
|
||||
<input type="text" class="form-control" name="kakao_admin_key" id="kakao_admin_key"
|
||||
placeholder="카카오톡 API의 Admin Key"
|
||||
value="" />
|
||||
</div>
|
||||
@@ -133,7 +130,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-4"></div>
|
||||
<div class="col-sm-8">
|
||||
<button type="submit"
|
||||
<button type="submit"
|
||||
class="btn btn-primary btn-lg btn-block login-button">설정 파일 생성</button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -144,7 +141,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="card" id="admin_form_card" style="display:none">
|
||||
<h3 class="card-header">
|
||||
설치(관리자 생성)
|
||||
</h3>
|
||||
</h3>
|
||||
<div class="card-body">
|
||||
<form id="admin_form" method="post" action="#">
|
||||
<div class="form-group row">
|
||||
@@ -155,11 +152,11 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="password" class="col-sm-3 col-form-label">비밀번호</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="password" class="form-control" name="password" id="password"
|
||||
<input type="password" class="form-control" name="password" id="password"
|
||||
placeholder="비밀번호"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -167,7 +164,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="confirm_password" class="col-sm-3 col-form-label">비밀번호 확인</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="password" class="form-control" name="confirm_password" id="confirm_password"
|
||||
<input type="password" class="form-control" name="confirm_password" id="confirm_password"
|
||||
placeholder="비밀번호 확인"/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -175,7 +172,7 @@ require(__DIR__.'/../vendor/autoload.php');
|
||||
<div class="form-group row">
|
||||
<label for="nickname" class="col-sm-3 col-form-label">닉네임</label>
|
||||
<div class="col-sm-9">
|
||||
<input type="text" class="form-control" name="nickname" id="nickname"
|
||||
<input type="text" class="form-control" name="nickname" id="nickname"
|
||||
placeholder="닉네임" value="운영자"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+313
-305
@@ -1,305 +1,313 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
require(__DIR__ . '/../vendor/autoload.php');
|
||||
|
||||
$host = Util::getPost('db_host');
|
||||
$port = Util::getPost('db_port', 'int');
|
||||
$username = Util::getPost('db_id');
|
||||
$password = Util::getPost('db_pw');
|
||||
$dbName = Util::getPost('db_name');
|
||||
$servHost = Util::getPost('serv_host');
|
||||
$sharedIconPath = Util::getPost('shared_icon_path');
|
||||
$gameImagePath = Util::getPost('game_image_path');
|
||||
$imageRequestKey = Util::getPost('image_request_key');
|
||||
|
||||
$kakaoRESTKey = Util::getPost('kakao_rest_key', 'string', '');
|
||||
$kakaoAdminKey = Util::getPost('kakao_admin_key', 'string', '');
|
||||
|
||||
|
||||
if (!$host || !$port || !$username || !$password || !$dbName || !$servHost || !$sharedIconPath || !$gameImagePath) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '입력 값이 올바르지 않습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!filter_var($servHost, FILTER_VALIDATE_URL)) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '접속 경로가 올바르지 않습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_setting/RootDB.php') && is_dir(ROOT . '/d_setting/RootDB.php')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_setting/RootDB.php 가 디렉토리입니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (class_exists('\\sammo\\RootDB')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '이미 RootDB.php 파일이 있습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
//파일 권한 검사
|
||||
if (file_exists(AppConf::getUserIconPathFS()) && !is_dir(AppConf::getUserIconPathFS())) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => AppConf::$userIconPath . ' 이 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_log') && !is_dir(ROOT . '/d_log')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_log 가 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_shared') && !is_dir(ROOT . '/d_shared')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_shared 가 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_setting') && !is_dir(ROOT . '/d_setting')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_shared 가 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (
|
||||
!file_exists(ROOT . '/d_log')
|
||||
|| !file_exists(ROOT . '/d_shared')
|
||||
|| !file_exists(ROOT . '/d_setting')
|
||||
|| !file_exists(AppConf::getUserIconPathFS())
|
||||
) {
|
||||
if (!is_writable(ROOT)) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '하위 디렉토리 생성 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
//기본 파일 생성
|
||||
if (!file_exists(AppConf::getUserIconPathFS())) {
|
||||
mkdir(AppConf::getUserIconPathFS());
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_log')) {
|
||||
mkdir(ROOT . '/d_log');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_setting')) {
|
||||
mkdir(ROOT . '/d_setting');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_shared')) {
|
||||
mkdir(ROOT . '/d_shared');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!is_writable(AppConf::getUserIconPathFS())) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => AppConf::$userIconPath . ' 디렉토리의 쓰기 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!is_writable(ROOT . '/d_log')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_log 디렉토리의 쓰기 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!is_writable(ROOT . '/d_shared')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_shared 디렉토리의 쓰기 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!is_writable(ROOT . '/d_setting')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_setting 디렉토리의 쓰기 권한이 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!file_exists(ROOT . '/d_log/.htaccess')) {
|
||||
@file_put_contents(ROOT . '/d_log/.htaccess', 'Deny from all');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_setting/.htaccess')) {
|
||||
@file_put_contents(ROOT . '/d_setting/.htaccess', 'Deny from all');
|
||||
}
|
||||
|
||||
//DB 접근 권한 검사
|
||||
|
||||
$rootDB = new \MeekroDB($host, $username, $password, $dbName, $port, 'utf8mb4');
|
||||
$rootDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
|
||||
|
||||
$rootDB->throw_exception_on_nonsql_error = false;
|
||||
$rootDB->nonsql_error_handler = function ($params) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'DB 접속에 실패했습니다.'
|
||||
]);
|
||||
};
|
||||
|
||||
$rootDB->error_handler = function ($params) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'SQL을 제대로 실행하지 못했습니다. DB상태를 확인해 주세요.'
|
||||
]);
|
||||
};
|
||||
|
||||
$mysqli_obj = $rootDB->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨.
|
||||
|
||||
if ($mysqli_obj->multi_query(file_get_contents(__DIR__ . '/sql/common_schema.sql'))) {
|
||||
while (true) {
|
||||
if (!$mysqli_obj->more_results()) {
|
||||
break;
|
||||
}
|
||||
if (!$mysqli_obj->next_result()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootDB->insert('system', array(
|
||||
'REG' => 'N',
|
||||
'LOGIN' => 'N',
|
||||
'CRT_DATE' => TimeUtil::now(),
|
||||
'MDF_DATE' => TimeUtil::now()
|
||||
));
|
||||
|
||||
$globalSalt = bin2hex(random_bytes(16));
|
||||
|
||||
'@phan-var-force string $servHost';
|
||||
'@phan-var-force string $sharedIconPath';
|
||||
'@phan-var-force string $gameImagePath';
|
||||
|
||||
$sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost);
|
||||
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
|
||||
$imageRequestPath = WebUtil::resolveRelativePath($gameImagePath . '/../hook/git_pull.php', $servHost);
|
||||
$imageKeyInstallPath = WebUtil::resolveRelativePath($gameImagePath . '/../hook/InstallKey.php', $servHost);
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/ServConfig.orig.php',
|
||||
ROOT . '/d_setting/ServConfig.php',
|
||||
[
|
||||
'serverBasePath' => $servHost,
|
||||
'sharedIconPath' => $sharedIconPath,
|
||||
'gameImagePath' => $gameImagePath,
|
||||
'imageRequestPath' => $imageRequestPath,
|
||||
'imageRequestKey' => $imageRequestKey
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ($imageRequestKey) {
|
||||
@file_get_contents($imageKeyInstallPath . '?key=' . $imageRequestKey);
|
||||
}
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/common_path.orig.js',
|
||||
ROOT . '/d_shared/common_path.js',
|
||||
[
|
||||
'serverBasePath' => $servHost,
|
||||
'sharedIconPath' => $sharedIconPath,
|
||||
'gameImagePath' => $gameImagePath
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/menu.orig.json',
|
||||
ROOT . '/d_shared/menu.json',
|
||||
[],
|
||||
true
|
||||
);
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/common.orig.css',
|
||||
ROOT . '/d_shared/common.css',
|
||||
[
|
||||
'serverBasePath' => $servHost,
|
||||
'sharedIconPath' => $sharedIconPath,
|
||||
'gameImagePath' => $gameImagePath
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/RootDB.orig.php',
|
||||
ROOT . '/d_setting/RootDB.php',
|
||||
[
|
||||
'host' => $host,
|
||||
'user' => $username,
|
||||
'password' => $password,
|
||||
'dbName' => $dbName,
|
||||
'port' => $port,
|
||||
'globalSalt' => $globalSalt,
|
||||
]
|
||||
);
|
||||
|
||||
$kakaoRedirectURI = WebUtil::resolveRelativePath('oauth_kakao/oauth.php', $servHost . '/');
|
||||
|
||||
Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/KakaoKey.orig.php',
|
||||
ROOT . '/d_setting/KakaoKey.php',
|
||||
[
|
||||
'REST_API_KEY' => $kakaoRESTKey,
|
||||
'ADMIN_KEY' => $kakaoAdminKey,
|
||||
'REDIRECT_URI' => $kakaoRedirectURI
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success',
|
||||
'globalSalt' => $globalSalt
|
||||
]);
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
require(__DIR__ . '/../vendor/autoload.php');
|
||||
|
||||
$host = Util::getPost('db_host');
|
||||
$port = Util::getPost('db_port', 'int');
|
||||
$username = Util::getPost('db_id');
|
||||
$password = Util::getPost('db_pw');
|
||||
$dbName = Util::getPost('db_name');
|
||||
$servHost = Util::getPost('serv_host');
|
||||
$sharedIconPath = Util::getPost('shared_icon_path');
|
||||
$gameImagePath = Util::getPost('game_image_path');
|
||||
$imageRequestKey = Util::getPost('image_request_key');
|
||||
|
||||
$kakaoRESTKey = Util::getPost('kakao_rest_key', 'string', '');
|
||||
$kakaoAdminKey = Util::getPost('kakao_admin_key', 'string', '');
|
||||
|
||||
|
||||
if (!$host || !$port || !$username || !$password || !$dbName || !$servHost || !$sharedIconPath || !$gameImagePath) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '입력 값이 올바르지 않습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!filter_var($servHost, FILTER_VALIDATE_URL)) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '접속 경로가 올바르지 않습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_setting/RootDB.php') && is_dir(ROOT . '/d_setting/RootDB.php')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_setting/RootDB.php 가 디렉토리입니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (class_exists('\\sammo\\RootDB')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '이미 RootDB.php 파일이 있습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
//파일 권한 검사
|
||||
if (file_exists(AppConf::getUserIconPathFS()) && !is_dir(AppConf::getUserIconPathFS())) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => AppConf::$userIconPath . ' 이 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_log') && !is_dir(ROOT . '/d_log')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_log 가 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_shared') && !is_dir(ROOT . '/d_shared')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_shared 가 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (file_exists(ROOT . '/d_setting') && !is_dir(ROOT . '/d_setting')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_shared 가 디렉토리가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (
|
||||
!file_exists(ROOT . '/d_log')
|
||||
|| !file_exists(ROOT . '/d_shared')
|
||||
|| !file_exists(ROOT . '/d_setting')
|
||||
|| !file_exists(AppConf::getUserIconPathFS())
|
||||
) {
|
||||
if (!is_writable(ROOT)) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '하위 디렉토리 생성 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
//기본 파일 생성
|
||||
if (!file_exists(AppConf::getUserIconPathFS())) {
|
||||
mkdir(AppConf::getUserIconPathFS());
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_log')) {
|
||||
mkdir(ROOT . '/d_log');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_setting')) {
|
||||
mkdir(ROOT . '/d_setting');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_shared')) {
|
||||
mkdir(ROOT . '/d_shared');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!is_writable(AppConf::getUserIconPathFS())) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => AppConf::$userIconPath . ' 디렉토리의 쓰기 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!is_writable(ROOT . '/d_log')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_log 디렉토리의 쓰기 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!is_writable(ROOT . '/d_shared')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_shared 디렉토리의 쓰기 권한이 없습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if (!is_writable(ROOT . '/d_setting')) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'd_setting 디렉토리의 쓰기 권한이 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (!file_exists(ROOT . '/d_log/.htaccess')) {
|
||||
@file_put_contents(ROOT . '/d_log/.htaccess', 'Deny from all');
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_setting/.htaccess')) {
|
||||
@file_put_contents(ROOT . '/d_setting/.htaccess', 'Deny from all');
|
||||
}
|
||||
|
||||
//DB 접근 권한 검사
|
||||
|
||||
$rootDB = new \MeekroDB($host, $username, $password, $dbName, $port, 'utf8mb4');
|
||||
$rootDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
|
||||
|
||||
$rootDB->throw_exception_on_nonsql_error = false;
|
||||
$rootDB->nonsql_error_handler = function ($params) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'DB 접속에 실패했습니다.'
|
||||
]);
|
||||
};
|
||||
|
||||
$rootDB->error_handler = function ($params) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => 'SQL을 제대로 실행하지 못했습니다. DB상태를 확인해 주세요.'
|
||||
]);
|
||||
};
|
||||
|
||||
$mysqli_obj = $rootDB->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨.
|
||||
|
||||
if ($mysqli_obj->multi_query(file_get_contents(__DIR__ . '/sql/common_schema.sql'))) {
|
||||
while (true) {
|
||||
if (!$mysqli_obj->more_results()) {
|
||||
break;
|
||||
}
|
||||
if (!$mysqli_obj->next_result()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$rootDB->insert('system', array(
|
||||
'REG' => 'N',
|
||||
'LOGIN' => 'N',
|
||||
'CRT_DATE' => TimeUtil::now(),
|
||||
'MDF_DATE' => TimeUtil::now()
|
||||
));
|
||||
|
||||
$globalSalt = bin2hex(random_bytes(16));
|
||||
|
||||
'@phan-var-force string $servHost';
|
||||
'@phan-var-force string $sharedIconPath';
|
||||
'@phan-var-force string $gameImagePath';
|
||||
|
||||
$sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost);
|
||||
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
|
||||
$imageRequestPath = WebUtil::resolveRelativePath($gameImagePath . '/../hook/git_pull.php', $servHost);
|
||||
$imageKeyInstallPath = WebUtil::resolveRelativePath($gameImagePath . '/../hook/InstallKey.php', $servHost);
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/ServConfig.orig.php',
|
||||
ROOT . '/d_setting/ServConfig.php',
|
||||
[
|
||||
'serverBasePath' => $servHost,
|
||||
'sharedIconPath' => $sharedIconPath,
|
||||
'gameImagePath' => $gameImagePath,
|
||||
'imageRequestPath' => $imageRequestPath,
|
||||
'imageRequestKey' => $imageRequestKey,
|
||||
'serverList' => [
|
||||
['che', '체', 'white'],
|
||||
['kwe', '퀘', 'yellow'],
|
||||
['pwe', '풰', 'orange'],
|
||||
['twe', '퉤', 'magenta'],
|
||||
['nya', '냐', '#e67e22'],
|
||||
['pya', '퍄', '#9b59b6']
|
||||
]
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ($imageRequestKey) {
|
||||
@file_get_contents($imageKeyInstallPath . '?key=' . $imageRequestKey);
|
||||
}
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/common_path.orig.js',
|
||||
ROOT . '/d_shared/common_path.js',
|
||||
[
|
||||
'serverBasePath' => $servHost,
|
||||
'sharedIconPath' => $sharedIconPath,
|
||||
'gameImagePath' => $gameImagePath
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/menu.orig.json',
|
||||
ROOT . '/d_shared/menu.json',
|
||||
[],
|
||||
true
|
||||
);
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/common.orig.css',
|
||||
ROOT . '/d_shared/common.css',
|
||||
[
|
||||
'serverBasePath' => $servHost,
|
||||
'sharedIconPath' => $sharedIconPath,
|
||||
'gameImagePath' => $gameImagePath
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/RootDB.orig.php',
|
||||
ROOT . '/d_setting/RootDB.php',
|
||||
[
|
||||
'host' => $host,
|
||||
'user' => $username,
|
||||
'password' => $password,
|
||||
'dbName' => $dbName,
|
||||
'port' => $port,
|
||||
'globalSalt' => $globalSalt,
|
||||
]
|
||||
);
|
||||
|
||||
$kakaoRedirectURI = WebUtil::resolveRelativePath('oauth_kakao/oauth.php', $servHost . '/');
|
||||
|
||||
Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__ . '/templates/KakaoKey.orig.php',
|
||||
ROOT . '/d_setting/KakaoKey.php',
|
||||
[
|
||||
'REST_API_KEY' => $kakaoRESTKey,
|
||||
'ADMIN_KEY' => $kakaoAdminKey,
|
||||
'REDIRECT_URI' => $kakaoRedirectURI
|
||||
],
|
||||
true
|
||||
);
|
||||
|
||||
if ($result !== true) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => $result
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'success',
|
||||
'globalSalt' => $globalSalt
|
||||
]);
|
||||
|
||||
@@ -58,7 +58,7 @@ CREATE TABLE `member_log` (
|
||||
INDEX `action` (`member_no`, `action_type`, `date`),
|
||||
INDEX `member` (`member_no`, `date`)
|
||||
)
|
||||
ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
||||
ENGINE=Aria DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
###################
|
||||
# KV storage
|
||||
@@ -72,4 +72,19 @@ CREATE TABLE if not exists `storage` (
|
||||
UNIQUE INDEX `key` (`namespace`, `key`)
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci'
|
||||
ENGINE=MyISAM
|
||||
ENGINE=Aria;
|
||||
|
||||
CREATE TABLE `login_token` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT(11) NOT NULL,
|
||||
`base_token` VARCHAR(20) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`reg_ip` VARCHAR(40) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`reg_date` DATETIME NOT NULL,
|
||||
`expire_date` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `by_token` (`base_token`),
|
||||
INDEX `by_date` (`user_id`, `expire_date`)
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci'
|
||||
ENGINE=Aria
|
||||
;
|
||||
@@ -1,6 +1,7 @@
|
||||
<?php
|
||||
namespace kakao;
|
||||
|
||||
// @suppress PhanRedefineClass
|
||||
class KakaoKey{
|
||||
const REST_KEY = '_tK_REST_API_KEY_';
|
||||
const ADMIN_KEY = '_tK_ADMIN_KEY_';
|
||||
|
||||
@@ -2,9 +2,15 @@
|
||||
|
||||
namespace sammo;
|
||||
|
||||
//https://hub.packtpub.com/eloquent-without-laravel/
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
class RootDB
|
||||
{
|
||||
private static $uDB = null;
|
||||
private static ?Capsule $uIlluminate = null;
|
||||
|
||||
private static $host = '_tK_host_';
|
||||
private static $user = '_tK_user_';
|
||||
@@ -12,6 +18,8 @@ class RootDB
|
||||
private static $dbName = '_tK_dbName_';
|
||||
private static $port = _tK_port_;
|
||||
private static $encoding = 'utf8mb4';
|
||||
private static $collation = 'utf8mb4_general_ci';
|
||||
|
||||
|
||||
private static $globalSalt = '_tK_globalSalt_';
|
||||
|
||||
@@ -19,6 +27,29 @@ class RootDB
|
||||
{
|
||||
}
|
||||
|
||||
public static function illuminate(): Capsule
|
||||
{
|
||||
if(self::$uIlluminate !== null){
|
||||
return self::$uIlluminate;
|
||||
}
|
||||
$capsule = new Capsule;
|
||||
|
||||
$capsule->addConnection([
|
||||
'driver' => 'mysql',
|
||||
'host' => self::$host,
|
||||
'database' => self::$dbName,
|
||||
'username' => self::$user,
|
||||
'password' => self::$password,
|
||||
'charset' => self::$encoding,
|
||||
'collation' => self::$collation,
|
||||
], 'root');
|
||||
|
||||
$capsule->setEventDispatcher(new Dispatcher(new Container));
|
||||
$capsule->bootEloquent();
|
||||
self::$uIlluminate = $capsule;
|
||||
return $capsule;
|
||||
}
|
||||
|
||||
/**
|
||||
* DB 객체 생성
|
||||
*
|
||||
|
||||
@@ -1,55 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
class ServConfig
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static $serverWebPath = '_tK_serverBasePath_';
|
||||
public static $sharedIconPath = '_tK_sharedIconPath_';
|
||||
public static $gameImagePath = "_tK_gameImagePath_";
|
||||
public static $imageRequestPath = "_tK_imageRequestPath_";
|
||||
public static $imageRequestKey = '_tK_imageRequestKey_';
|
||||
|
||||
public static function getSharedIconPath(string $filepath = ''): string
|
||||
{
|
||||
if ($filepath) {
|
||||
return static::$sharedIconPath . "/{$filepath}";
|
||||
}
|
||||
return static::$sharedIconPath;
|
||||
}
|
||||
|
||||
public static function getUserIconPath(string $filepath = ''): string
|
||||
{
|
||||
return AppConf::getUserIconPathWeb($filepath);
|
||||
}
|
||||
|
||||
public static function getGameImagePath(string $filepath = ''): string
|
||||
{
|
||||
if ($filepath) {
|
||||
return static::$gameImagePath . "/{$filepath}";
|
||||
}
|
||||
return static::$gameImagePath;
|
||||
}
|
||||
|
||||
public static function getImagePullURI(): string
|
||||
{
|
||||
$now = time();
|
||||
$req_hash = Util::hashPassword(sprintf("%016x", $now), static::$imageRequestKey);
|
||||
return static::$imageRequestPath . "?req={$req_hash}&time={$now}";
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 서버 주소 반환. 서버의 경로가 하부 디렉토리인 경우에 하부 디렉토리까지 포함
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getServerBasepath(): string
|
||||
{
|
||||
return self::$serverWebPath;
|
||||
}
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
class ServConfig
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static $serverWebPath = '_tK_serverBasePath_';
|
||||
public static $sharedIconPath = '_tK_sharedIconPath_';
|
||||
public static $gameImagePath = "_tK_gameImagePath_";
|
||||
public static $imageRequestPath = "_tK_imageRequestPath_";
|
||||
public static $imageRequestKey = '_tK_imageRequestKey_';
|
||||
private static $serverList = null;
|
||||
|
||||
public static function getSharedIconPath(string $filepath = ''): string
|
||||
{
|
||||
if ($filepath) {
|
||||
return static::$sharedIconPath . "/{$filepath}";
|
||||
}
|
||||
return static::$sharedIconPath;
|
||||
}
|
||||
|
||||
public static function getUserIconPath(string $filepath = ''): string
|
||||
{
|
||||
return AppConf::getUserIconPathWeb($filepath);
|
||||
}
|
||||
|
||||
public static function getGameImagePath(string $filepath = ''): string
|
||||
{
|
||||
if ($filepath) {
|
||||
return static::$gameImagePath . "/{$filepath}";
|
||||
}
|
||||
return static::$gameImagePath;
|
||||
}
|
||||
|
||||
public static function getImagePullURI(): string
|
||||
{
|
||||
$now = time();
|
||||
$req_hash = Util::hashPassword(sprintf("%016x", $now), static::$imageRequestKey);
|
||||
return static::$imageRequestPath . "?req={$req_hash}&time={$now}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 서버 설정 반환
|
||||
*
|
||||
* @return \sammo\Setting[]
|
||||
*/
|
||||
public static function getServerList(): array{
|
||||
$servKeyList = [/*_tK_serverList_*/];
|
||||
$servKeyList[] = ['hwe', '훼', 'red'];
|
||||
|
||||
if (self::$serverList === null) {
|
||||
self::$serverList = [];
|
||||
foreach($servKeyList as [$servKey, $servNick, $servColor]){
|
||||
self::$serverList[$servKey] = new Setting(ROOT.'/'.$servKey, $servNick, $servColor);
|
||||
}
|
||||
}
|
||||
return self::$serverList;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 서버 주소 반환. 서버의 경로가 하부 디렉토리인 경우에 하부 디렉토리까지 포함
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function getServerBasepath(): string
|
||||
{
|
||||
return self::$serverWebPath;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,38 +6,33 @@
|
||||
|
||||
.img_back {background-image:url('_tK_gameImagePath_/back.jpg'); }
|
||||
|
||||
/* 레거시. */
|
||||
#bg0 { background-image:url('_tK_gameImagePath_/back_walnut.jpg'); }
|
||||
#bg1 { background-image:url('_tK_gameImagePath_/back_green.jpg'); }
|
||||
#bg2 { background-image:url('_tK_gameImagePath_/back_blue.jpg'); }
|
||||
|
||||
.map_detail .map_title{
|
||||
background:
|
||||
url('_tK_gameImagePath_/ltitle.jpg') no-repeat left,
|
||||
url('_tK_gameImagePath_/ltitle.jpg') no-repeat left,
|
||||
url('_tK_gameImagePath_/rtitle.jpg') no-repeat right;
|
||||
}
|
||||
|
||||
.map_detail.map_spring .map_title_text{
|
||||
background:
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/spring.gif') no-repeat right;
|
||||
}
|
||||
|
||||
.map_detail.map_summer .map_title_text{
|
||||
background:
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/summer.gif') no-repeat right;
|
||||
}
|
||||
|
||||
.map_detail.map_fall .map_title_text{
|
||||
background:
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/fall.gif') no-repeat right;
|
||||
}
|
||||
|
||||
.map_detail.map_winter .map_title_text{
|
||||
background:
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/ad.gif') no-repeat left,
|
||||
url('_tK_gameImagePath_/winter.gif') no-repeat right;
|
||||
}
|
||||
|
||||
|
||||
@@ -342,6 +342,7 @@ switch ($btn) {
|
||||
}
|
||||
break;
|
||||
case "랜덤턴":
|
||||
$turnterm = $gameStor->turnterm;
|
||||
foreach ($genlist as $generalID) {
|
||||
$turntime = getRandTurn($turnterm);
|
||||
$db->update('general', [
|
||||
|
||||
+2
-2
@@ -99,7 +99,7 @@ $sel2[$type2] = "selected";
|
||||
</table>
|
||||
|
||||
<table align=center width=1600 class="tb_layout bg0">
|
||||
<tr id=bg1>
|
||||
<tr class='bg1'>
|
||||
<td align=center>국명</td>
|
||||
<td align=center>접률</td>
|
||||
<td align=center>단접</td>
|
||||
@@ -278,7 +278,7 @@ from city where nation=%i', $nation['nation']);
|
||||
</table>
|
||||
|
||||
<table align=center width=1760 class="tb_layout bg0">
|
||||
<tr id=bg1>
|
||||
<tr class='bg1'>
|
||||
<td width=30 align=center>년</td>
|
||||
<td width=30 align=center>월</td>
|
||||
<td width=50 align=center>국가수</td>
|
||||
|
||||
+9
-9
@@ -52,9 +52,9 @@ if ($reqArgType === 0) {
|
||||
$generalBasicList = $db->query('SELECT no, name, nation, npc, turntime, %b FROM general', $reqQueryType);
|
||||
} else if ($reqArgType === 2) {
|
||||
$generalBasicList = $db->query(
|
||||
'SELECT no, name, nation, npc, turntime, value as %b
|
||||
FROM general LEFT JOIN rank_data
|
||||
ON general.no = rank_data.general_id
|
||||
'SELECT no, name, nation, npc, turntime, value as %b
|
||||
FROM general LEFT JOIN rank_data
|
||||
ON general.no = rank_data.general_id
|
||||
WHERE rank_data.type = %s',
|
||||
$reqQueryType,
|
||||
$reqQueryType
|
||||
@@ -117,10 +117,10 @@ $generalObj = General::createGeneralObjFromDB($gen);
|
||||
</table>
|
||||
<table width=1000 align=center class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=50% align=center id=bg1>
|
||||
<td width=50% align=center class='bg1'>
|
||||
<font color=skyblue size=3>장 수 정 보</font>
|
||||
</td>
|
||||
<td width=50% align=center id=bg1>
|
||||
<td width=50% align=center class='bg1'>
|
||||
<font color=orange size=3>-</font>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -133,10 +133,10 @@ $generalObj = General::createGeneralObjFromDB($gen);
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>
|
||||
<td align=center class='bg1'>
|
||||
<font color=skyblue size=3>개인 기록</font>
|
||||
</td>
|
||||
<td align=center id=bg1>
|
||||
<td align=center class='bg1'>
|
||||
<font color=orange size=3>전투 기록</font>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -149,10 +149,10 @@ $generalObj = General::createGeneralObjFromDB($gen);
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>
|
||||
<td align=center class='bg1'>
|
||||
<font color=skyblue size=3>장수 열전</font>
|
||||
</td>
|
||||
<td align=center id=bg1>
|
||||
<td align=center class='bg1'>
|
||||
<font color=orange size=3>전투 결과</font>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
+4
-4
@@ -49,10 +49,10 @@ $sel[$type] = "selected";
|
||||
<table width=1000 align=center class='tb_layout bg0'>
|
||||
<tr><td colspan=9 align=center bgcolor=blue>외 교 관 계</td></tr>
|
||||
<tr>
|
||||
<td width=130 align=center id=bg1>국 가 명</td>
|
||||
<td width=130 align=center id=bg1>국 가 명</td>
|
||||
<td width=80 align=center id=bg1>상 태</td>
|
||||
<td width=60 align=center id=bg1>기 간</td>
|
||||
<td width=130 align=center class='bg1'>국 가 명</td>
|
||||
<td width=130 align=center class='bg1'>국 가 명</td>
|
||||
<td width=80 align=center class='bg1'>상 태</td>
|
||||
<td width=60 align=center class='bg1'>기 간</td>
|
||||
</tr>
|
||||
<?php
|
||||
|
||||
|
||||
@@ -24,3 +24,7 @@ foreach ($db->queryFirstColumn(
|
||||
) as $generalNo) {
|
||||
CheckHall($generalNo);
|
||||
}
|
||||
|
||||
foreach(General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj){
|
||||
$genObj->mergeTotalInheritancePoint();
|
||||
}
|
||||
+16
-18
@@ -29,10 +29,9 @@ $templates = new \League\Plates\Engine(__DIR__.'/templates');
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printCSS('css/hallOfFame.css')?>
|
||||
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -74,7 +73,7 @@ $types = [
|
||||
}
|
||||
$v['nationName'] = '???';
|
||||
$v['pictureFullPath'] = GetImageURL(0)."/default.jpg";
|
||||
$v['name'] = '???';
|
||||
$v['name'] = '???';
|
||||
$v['ownerName'] = null;
|
||||
$v['bgColor'] = GameConst::$basecolor4;
|
||||
$v['fgColor'] = newColor($v['bgColor']);
|
||||
@@ -123,9 +122,9 @@ $types = [
|
||||
$v['value'] = 0;
|
||||
}
|
||||
else{
|
||||
$v['value'] = $v['ttw']/max(1, $totalCnt);
|
||||
$v['value'] = $v['ttw']/max(1, $totalCnt);
|
||||
}
|
||||
return $v;
|
||||
return $v;
|
||||
}],
|
||||
["통 솔 전 승 률", "percent", function($v){
|
||||
$totalCnt = $v['tlw']+$v['tld']+$v['tll'];
|
||||
@@ -135,7 +134,7 @@ $types = [
|
||||
else{
|
||||
$v['value'] = $v['tlw']/max(1, $totalCnt);
|
||||
}
|
||||
return $v;
|
||||
return $v;
|
||||
}],
|
||||
["일 기 토 승 률", "percent", function($v){
|
||||
$totalCnt = $v['tsw']+$v['tsd']+$v['tsl'];
|
||||
@@ -155,7 +154,7 @@ $types = [
|
||||
else{
|
||||
$v['value'] = $v['tiw']/max(1, $totalCnt);
|
||||
}
|
||||
|
||||
|
||||
return $v;
|
||||
}],
|
||||
["베 팅 투 자 액", "int", function($v){$v['value'] = $v['betgold']; return $v; }],
|
||||
@@ -174,17 +173,17 @@ $types = [
|
||||
|
||||
$generals = [];
|
||||
foreach($db->query(
|
||||
"SELECT nation,no,name,owner_name as ownerName, owner, picture, imgsvr,
|
||||
"SELECT nation,no,name,owner_name as ownerName, owner, picture, imgsvr,
|
||||
experience, dedication,
|
||||
dex1, dex2, dex3, dex4, dex5,
|
||||
horse, weapon, book, item
|
||||
dex1, dex2, dex3, dex4, dex5,
|
||||
horse, weapon, book, item
|
||||
FROM general WHERE %l", $btn == "NPC 보기"?"npc>=2":"npc<2") as $general
|
||||
){
|
||||
$generalID = $general['no'];
|
||||
$general['bgColor'] = $nationColor[$general['nation']]??GameConst::$basecolor4;
|
||||
$general['fgColor'] = newColor($general['bgColor']);
|
||||
$general['nationName'] = $nationName[$general['nation']];
|
||||
|
||||
|
||||
if(key_exists('picture', $general)){
|
||||
$imageTemp = GetImageURL($general['imgsvr']);
|
||||
$general['pictureFullPath'] = "$imageTemp/{$general['picture']}";
|
||||
@@ -265,7 +264,7 @@ foreach($generals as $general){
|
||||
else{
|
||||
$itemOwners[$itemClassName] = [$general];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +279,7 @@ foreach(GameConst::$allItems as $itemType=>$itemList){
|
||||
continue;
|
||||
}
|
||||
$itemClass = buildItemClass($itemClassName);
|
||||
|
||||
|
||||
if($itemClass->isBuyable()){
|
||||
continue;
|
||||
}
|
||||
@@ -288,7 +287,7 @@ foreach(GameConst::$allItems as $itemType=>$itemList){
|
||||
$info = $itemClass->getInfo();
|
||||
$name = $itemClass->getName();
|
||||
|
||||
|
||||
|
||||
if($info){
|
||||
$name = $templates->render('tooltip', [
|
||||
'text'=>$name,
|
||||
@@ -323,7 +322,7 @@ foreach(GameConst::$allItems as $itemType=>$itemList){
|
||||
$itemRanker[] = $card;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
echo $templates->render('hallOfFrame', [
|
||||
'typeName'=>$itemNameType,
|
||||
'generals'=>$itemRanker
|
||||
@@ -337,4 +336,3 @@ foreach(GameConst::$allItems as $itemType=>$itemList){
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
+17
-17
@@ -16,9 +16,9 @@ increaseRefresh("왕조일람", 1);
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 왕조일람</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -70,9 +70,9 @@ foreach($emperiors as $emperior){
|
||||
<tr>
|
||||
<td bgcolor=skyblue align=center colspan=8>
|
||||
<font size=5><?=$emperior['phase']?></font>
|
||||
|
||||
|
||||
<a href="a_emperior_detail.php?select=<?=$emperior['no']?>"><button type='button'>자세히</button></a>
|
||||
|
||||
|
||||
<?php if($emperior['server_id']): ?>
|
||||
<a href="a_history.php?serverID=<?=$emperior['server_id']?>"><button type='button'>역사 보기</button></a>
|
||||
<?php endif ?>
|
||||
@@ -84,33 +84,33 @@ foreach($emperiors as $emperior){
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center width=80>국 력</td>
|
||||
<td class='bg1' align=center width=80>국 력</td>
|
||||
<td align=center width=170><?=$emperior['power']?></td>
|
||||
<td id=bg1 align=center width=80>장 수</td>
|
||||
<td class='bg1' align=center width=80>장 수</td>
|
||||
<td align=center width=170><?=$emperior['gennum']?></td>
|
||||
<td id=bg1 align=center width=80>속 령</td>
|
||||
<td class='bg1' align=center width=80>속 령</td>
|
||||
<td align=center width=170><?=$emperior['citynum']?></td>
|
||||
<td id=bg1 align=center width=80>성 향</td>
|
||||
<td class='bg1' align=center width=80>성 향</td>
|
||||
<td align=center width=170><?=$emperior['type']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>황 제</td>
|
||||
<td class='bg1' align=center>황 제</td>
|
||||
<td align=center><?=$emperior['l12name']?></td>
|
||||
<td id=bg1 align=center>승 상</td>
|
||||
<td class='bg1' align=center>승 상</td>
|
||||
<td align=center><?=$emperior['l11name']?></td>
|
||||
<td id=bg1 align=center>표 기 장 군</td>
|
||||
<td class='bg1' align=center>표 기 장 군</td>
|
||||
<td align=center><?=$emperior['l10name']?></td>
|
||||
<td id=bg1 align=center>사 공</td>
|
||||
<td class='bg1' align=center>사 공</td>
|
||||
<td align=center><?=$emperior['l9name']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>거 기 장 군</td>
|
||||
<td class='bg1' align=center>거 기 장 군</td>
|
||||
<td align=center><?=$emperior['l8name']?></td>
|
||||
<td id=bg1 align=center>태 위</td>
|
||||
<td class='bg1' align=center>태 위</td>
|
||||
<td align=center><?=$emperior['l7name']?></td>
|
||||
<td id=bg1 align=center>위 장 군</td>
|
||||
<td class='bg1' align=center>위 장 군</td>
|
||||
<td align=center><?=$emperior['l6name']?></td>
|
||||
<td id=bg1 align=center>사 도</td>
|
||||
<td class='bg1' align=center>사 도</td>
|
||||
<td align=center><?=$emperior['l5name']?></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
+28
-31
@@ -26,9 +26,6 @@ $serverID = $emperior['server_id']??($emperior['serverID']??null);
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 왕조일람</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -57,25 +54,25 @@ if($emperior):
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 width=98 align=center>국 가 수<br>(최종 / 최대)</td>
|
||||
<td class='bg1' width=98 align=center>국 가 수<br>(최종 / 최대)</td>
|
||||
<td align=center width=398 colspan=2><?=$emperior['nation_count']?></td>
|
||||
<td id=bg1 width=98 align=center>장 수 수<br>(최종 / 최대)</td>
|
||||
<td class='bg1' width=98 align=center>장 수 수<br>(최종 / 최대)</td>
|
||||
<td align=center width=398 colspan=2><?=$emperior['gen_count']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>등 장 국 가</td>
|
||||
<td class='bg1' align=center>등 장 국 가</td>
|
||||
<td colspan=5><?=$emperior['nation_name']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>국가별 성향</td>
|
||||
<td class='bg1' align=center>국가별 성향</td>
|
||||
<td colspan=5><?=$emperior['nation_hist']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>장 수 성 격</td>
|
||||
<td class='bg1' align=center>장 수 성 격</td>
|
||||
<td colspan=5><?=$emperior['personal_hist']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>장 수 특 기</td>
|
||||
<td class='bg1' align=center>장 수 특 기</td>
|
||||
<td colspan=5><?=$emperior['special_hist']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -84,75 +81,75 @@ if($emperior):
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 width=98 align=center>국 력</td>
|
||||
<td class='bg1' width=98 align=center>국 력</td>
|
||||
<td align=center width=398 colspan=2><?=$emperior['power']?></td>
|
||||
<td id=bg1 width=98 align=center>성 향</td>
|
||||
<td class='bg1' width=98 align=center>성 향</td>
|
||||
<td align=center width=398 colspan=2><?=$emperior['type']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 width=98 align=center>장 수</td>
|
||||
<td class='bg1' width=98 align=center>장 수</td>
|
||||
<td align=center width=398 colspan=2><?=$emperior['gennum']?></td>
|
||||
<td id=bg1 width=98 align=center>속 령</td>
|
||||
<td class='bg1' width=98 align=center>속 령</td>
|
||||
<td align=center width=398 colspan=2><?=$emperior['citynum']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>총 인 구</td>
|
||||
<td class='bg1' align=center>총 인 구</td>
|
||||
<td align=center colspan=2><?=$emperior['pop']?></td>
|
||||
<td id=bg1 align=center>인 구 율</td>
|
||||
<td class='bg1' align=center>인 구 율</td>
|
||||
<td align=center colspan=2><?=$emperior['poprate']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>국 고</td>
|
||||
<td class='bg1' align=center>국 고</td>
|
||||
<td align=center colspan=2><?=$emperior['gold']?></td>
|
||||
<td id=bg1 align=center>병 량</td>
|
||||
<td class='bg1' align=center>병 량</td>
|
||||
<td align=center colspan=2><?=$emperior['rice']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>황 제</td>
|
||||
<td class='bg1' align=center>황 제</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l12name']?></td>
|
||||
<td id=bg1 align=center>승 상</td>
|
||||
<td class='bg1' align=center>승 상</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l11name']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>위 장 군</td>
|
||||
<td class='bg1' align=center>위 장 군</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l10name']?></td>
|
||||
<td id=bg1 align=center>사 공</td>
|
||||
<td class='bg1' align=center>사 공</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l9name']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>표 기 장 군</td>
|
||||
<td class='bg1' align=center>표 기 장 군</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l8name']?></td>
|
||||
<td id=bg1 align=center>태 위</td>
|
||||
<td class='bg1' align=center>태 위</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l7name']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>거 기 장 군</td>
|
||||
<td class='bg1' align=center>거 기 장 군</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l6name']?></td>
|
||||
<td id=bg1 align=center>사 도</td>
|
||||
<td class='bg1' align=center>사 도</td>
|
||||
<td width=64> </td>
|
||||
<td width=332><?=$emperior['l5name']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>오 호 장 군</td>
|
||||
<td class='bg1' align=center>오 호 장 군</td>
|
||||
<td colspan=5><?=$emperior['tiger']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>건 안 칠 자</td>
|
||||
<td class='bg1' align=center>건 안 칠 자</td>
|
||||
<td colspan=5><?=$emperior['eagle']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>장 수 들<br>(공헌도 순서)</td>
|
||||
<td class='bg1' align=center>장 수 들<br>(공헌도 순서)</td>
|
||||
<td colspan=5><?=$emperior['gen']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td id=bg1 align=center>역 사 기 록</td>
|
||||
<td class='bg1' align=center>역 사 기 록</td>
|
||||
<td colspan=5><?=formatHistoryToHTML(Json::decode($emperior['history']))?></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -178,7 +175,7 @@ if($showServers){
|
||||
$nation['levelName'] = getNationLevel($nation['level']);
|
||||
/** @var int[]|null $nationGenerals */
|
||||
$nationGenerals = $nation['generals'];
|
||||
|
||||
|
||||
if($nationGenerals){
|
||||
$generals = $db->query('SELECT `general_no`, `name`, `last_yearmonth` FROM ng_old_generals WHERE server_id=%s AND general_no IN %li', $serverID, $nationGenerals);
|
||||
|
||||
@@ -203,7 +200,7 @@ if($showServers){
|
||||
if(key_exists('aux', $nation) && !is_array($nation['aux'])){
|
||||
$nation += Json::decode($nation['aux']);
|
||||
}
|
||||
|
||||
|
||||
echo $templates->render('oldNation', $nation);
|
||||
}
|
||||
}
|
||||
|
||||
+214
-215
@@ -1,215 +1,214 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$type = Util::getReq('type', 'int', 9);
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
increaseRefresh("장수일람", 2);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT con,turntime FROM general WHERE owner = %i', $userID);
|
||||
|
||||
$con = checkLimit($me['con']);
|
||||
if ($con >= 2) {
|
||||
printLimitMsg($me['turntime']);
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($type <= 0 || $type > 15) {
|
||||
$type = 9;
|
||||
}
|
||||
|
||||
$ownerNameList = [];
|
||||
if($gameStor->isunited){
|
||||
foreach(RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]){
|
||||
$ownerNameList[$ownerID] = $ownerName;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 장수일람</title>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td>장 수 일 람<br><?=closeButton()?></td></tr>
|
||||
<tr><td><form name=form1 method=post>정렬순서 :
|
||||
<select id='viewType' name='type' size=1>
|
||||
<option value=1>국가</option>
|
||||
<option value=2>통솔</option>
|
||||
<option value=3>무력</option>
|
||||
<option value=4>지력</option>
|
||||
<option value=5>명성</option>
|
||||
<option value=6>계급</option>
|
||||
<option value=7>관직</option>
|
||||
<option value=8>삭턴</option>
|
||||
<option value=9>벌점</option>
|
||||
<option value=10>Lv</option>
|
||||
<option value=11>성격</option>
|
||||
<option value=12>내특</option>
|
||||
<option value=13>전특</option>
|
||||
<option value=14>연령</option>
|
||||
<option value=15>NPC</option>
|
||||
</select>
|
||||
<input type=submit value='정렬하기'></form>
|
||||
</td></tr>
|
||||
</table>
|
||||
<?php
|
||||
$nationname = [];
|
||||
$nationlevel = [];
|
||||
$nationname[0] = "-";
|
||||
foreach (getAllNationStaticInfo() as $nation) {
|
||||
$nationname[$nation['nation']] = $nation['name'];
|
||||
$nationlevel[$nation['nation']] = $nation['level'];
|
||||
}
|
||||
|
||||
|
||||
[$orderKey, $orderDesc] = [
|
||||
1=>['nation', false],
|
||||
2=>['leadership', true],
|
||||
3=>['strength', true],
|
||||
4=>['intel', true],
|
||||
5=>['experience', true],
|
||||
6=>['dedication', true],
|
||||
7=>['officer_level', true],
|
||||
8=>['killturn', false],
|
||||
9=>['connect', true],
|
||||
10=>['experience', true],
|
||||
11=>['personal', true],
|
||||
12=>['special', true],
|
||||
13=>['special2', true],
|
||||
14=>['age', true],
|
||||
15=>['npc', true],
|
||||
][$type];
|
||||
|
||||
$generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general order by %b %l', $orderKey, $orderDesc?'desc':'');
|
||||
|
||||
echo"
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=64 align=center id=bg1>얼 굴</td>
|
||||
<td width=140 align=center id=bg1>이 름</td>
|
||||
<td width=45 align=center id=bg1>연령</td>
|
||||
<td width=45 align=center id=bg1>성격</td>
|
||||
<td width=80 align=center id=bg1>특기</td>
|
||||
<td width=45 align=center id=bg1>레 벨</td>
|
||||
<td width=140 align=center id=bg1>국 가</td>
|
||||
<td width=55 align=center id=bg1>명 성</td>
|
||||
<td width=55 align=center id=bg1>계 급</td>
|
||||
<td width=75 align=center id=bg1>관 직</td>
|
||||
<td width=45 align=center id=bg1>통솔</td>
|
||||
<td width=45 align=center id=bg1>무력</td>
|
||||
<td width=45 align=center id=bg1>지력</td>
|
||||
<td width=45 align=center id=bg1>삭턴</td>
|
||||
<td width=70 align=center id=bg1>벌점</td>
|
||||
</tr>";
|
||||
foreach($generalList as $general){
|
||||
$nation = $nationname[$general['nation']];
|
||||
|
||||
$lbonus = calcLeadershipBonus($general['officer_level'], $nationlevel[$general['nation']]??0);
|
||||
if ($lbonus > 0) {
|
||||
$lbonusText = "<font color=cyan>+{$lbonus}</font>";
|
||||
} else {
|
||||
$lbonusText = "";
|
||||
}
|
||||
|
||||
if ($general['injury'] > 0) {
|
||||
$leadership = intdiv($general['leadership'] * (100 - $general['injury']), 100);
|
||||
$strength = intdiv($general['strength'] * (100 - $general['injury']), 100);
|
||||
$intel = intdiv($general['intel'] * (100 - $general['injury']), 100);
|
||||
$leadership = "<font color=red>{$leadership}</font>{$lbonusText}";
|
||||
$strength = "<font color=red>{$strength}</font>";
|
||||
$intel = "<font color=red>{$intel}</font>";
|
||||
} else {
|
||||
$leadership = "{$general['leadership']}{$lbonusText}";
|
||||
$strength = "{$general['strength']}";
|
||||
$intel = "{$general['intel']}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($general['npc'] >= 2) {
|
||||
$name = "<font color=cyan>{$general['name']}</font>";
|
||||
} elseif ($general['npc'] == 1) {
|
||||
$name = "<font color=skyblue>{$general['name']}</font>";
|
||||
} else {
|
||||
$name = "{$general['name']}";
|
||||
}
|
||||
|
||||
if(key_exists($general['owner'], $ownerNameList)){
|
||||
$name = $name.'<br><small>('.$ownerNameList[$general['owner']].')</small>';
|
||||
}
|
||||
|
||||
$general['connect'] = Util::round($general['connect'], -1);
|
||||
|
||||
$imageTemp = GetImageURL($general['imgsvr']);
|
||||
echo "
|
||||
<tr data-general-id='{$general['no']}'
|
||||
data-general-wounded='{$general['injury']}'
|
||||
data-general-leadership='{$general['leadership']}'
|
||||
data-general-leadership-bonus='{$lbonus}'
|
||||
data-general-strength='{$general['strength']}'
|
||||
data-general-intel='{$general['intel']}'
|
||||
data-is-npc='".($general['npc']>=2?'true':'false')."'
|
||||
>
|
||||
<td align=center><img class='generalIcon' width='64' height='64' src='{$imageTemp}/{$general['picture']}'></img></td>
|
||||
<td align=center>$name</td>
|
||||
<td align=center>{$general['age']}세</td>
|
||||
<td align=center>".displayCharInfo($general['personal'])."</td>
|
||||
<td align=center>".displaySpecialDomesticInfo($general['special'])." / ".displaySpecialWarInfo($general['special2'])."</td>
|
||||
<td align=center>Lv ".getExpLevel($general['experience'])."</td>
|
||||
<td align=center>{$nation}</td>
|
||||
<td align=center>".getHonor($general['experience'])."</td>
|
||||
<td align=center>".getDed($general['dedication'])."</td>
|
||||
<td align=center>";
|
||||
echo getOfficerLevelText($general['officer_level']);
|
||||
echo "</td>
|
||||
<td align=center>$leadership</td>
|
||||
<td align=center>$strength</td>
|
||||
<td align=center>$intel</td>
|
||||
<td align=center>{$general['killturn']}</td>
|
||||
<td align=center>{$general['connect']}";
|
||||
echo "<br>【".getConnect($general['connect'])."】</td>
|
||||
</tr>";
|
||||
}
|
||||
echo "
|
||||
</table>
|
||||
";
|
||||
|
||||
?>
|
||||
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td><?=closeButton()?></td></tr>
|
||||
<tr><td><?=banner()?></td></tr>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("#viewType").val("<?=$type?>").attr("selected", "selected");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$type = Util::getReq('type', 'int', 9);
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
increaseRefresh("장수일람", 2);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT con,turntime FROM general WHERE owner = %i', $userID);
|
||||
|
||||
$con = checkLimit($me['con']);
|
||||
if ($con >= 2) {
|
||||
printLimitMsg($me['turntime']);
|
||||
exit();
|
||||
}
|
||||
|
||||
if ($type <= 0 || $type > 15) {
|
||||
$type = 9;
|
||||
}
|
||||
|
||||
$ownerNameList = [];
|
||||
if($gameStor->isunited){
|
||||
foreach(RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]){
|
||||
$ownerNameList[$ownerID] = $ownerName;
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 장수일람</title>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td>장 수 일 람<br><?=closeButton()?></td></tr>
|
||||
<tr><td><form name=form1 method=post>정렬순서 :
|
||||
<select id='viewType' name='type' size=1>
|
||||
<option value=1>국가</option>
|
||||
<option value=2>통솔</option>
|
||||
<option value=3>무력</option>
|
||||
<option value=4>지력</option>
|
||||
<option value=5>명성</option>
|
||||
<option value=6>계급</option>
|
||||
<option value=7>관직</option>
|
||||
<option value=8>삭턴</option>
|
||||
<option value=9>벌점</option>
|
||||
<option value=10>Lv</option>
|
||||
<option value=11>성격</option>
|
||||
<option value=12>내특</option>
|
||||
<option value=13>전특</option>
|
||||
<option value=14>연령</option>
|
||||
<option value=15>NPC</option>
|
||||
</select>
|
||||
<input type=submit value='정렬하기'></form>
|
||||
</td></tr>
|
||||
</table>
|
||||
<?php
|
||||
$nationname = [];
|
||||
$nationlevel = [];
|
||||
$nationname[0] = "-";
|
||||
foreach (getAllNationStaticInfo() as $nation) {
|
||||
$nationname[$nation['nation']] = $nation['name'];
|
||||
$nationlevel[$nation['nation']] = $nation['level'];
|
||||
}
|
||||
|
||||
|
||||
[$orderKey, $orderDesc] = [
|
||||
1=>['nation', false],
|
||||
2=>['leadership', true],
|
||||
3=>['strength', true],
|
||||
4=>['intel', true],
|
||||
5=>['experience', true],
|
||||
6=>['dedication', true],
|
||||
7=>['officer_level', true],
|
||||
8=>['killturn', false],
|
||||
9=>['connect', true],
|
||||
10=>['experience', true],
|
||||
11=>['personal', true],
|
||||
12=>['special', true],
|
||||
13=>['special2', true],
|
||||
14=>['age', true],
|
||||
15=>['npc', true],
|
||||
][$type];
|
||||
|
||||
$generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general order by %b %l', $orderKey, $orderDesc?'desc':'');
|
||||
|
||||
echo"
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=64 align=center class='bg1'>얼 굴</td>
|
||||
<td width=140 align=center class='bg1'>이 름</td>
|
||||
<td width=45 align=center class='bg1'>연령</td>
|
||||
<td width=45 align=center class='bg1'>성격</td>
|
||||
<td width=80 align=center class='bg1'>특기</td>
|
||||
<td width=45 align=center class='bg1'>레 벨</td>
|
||||
<td width=140 align=center class='bg1'>국 가</td>
|
||||
<td width=55 align=center class='bg1'>명 성</td>
|
||||
<td width=55 align=center class='bg1'>계 급</td>
|
||||
<td width=75 align=center class='bg1'>관 직</td>
|
||||
<td width=45 align=center class='bg1'>통솔</td>
|
||||
<td width=45 align=center class='bg1'>무력</td>
|
||||
<td width=45 align=center class='bg1'>지력</td>
|
||||
<td width=45 align=center class='bg1'>삭턴</td>
|
||||
<td width=70 align=center class='bg1'>벌점</td>
|
||||
</tr>";
|
||||
foreach($generalList as $general){
|
||||
$nation = $nationname[$general['nation']];
|
||||
|
||||
$lbonus = calcLeadershipBonus($general['officer_level'], $nationlevel[$general['nation']]??0);
|
||||
if ($lbonus > 0) {
|
||||
$lbonusText = "<font color=cyan>+{$lbonus}</font>";
|
||||
} else {
|
||||
$lbonusText = "";
|
||||
}
|
||||
|
||||
if ($general['injury'] > 0) {
|
||||
$leadership = intdiv($general['leadership'] * (100 - $general['injury']), 100);
|
||||
$strength = intdiv($general['strength'] * (100 - $general['injury']), 100);
|
||||
$intel = intdiv($general['intel'] * (100 - $general['injury']), 100);
|
||||
$leadership = "<font color=red>{$leadership}</font>{$lbonusText}";
|
||||
$strength = "<font color=red>{$strength}</font>";
|
||||
$intel = "<font color=red>{$intel}</font>";
|
||||
} else {
|
||||
$leadership = "{$general['leadership']}{$lbonusText}";
|
||||
$strength = "{$general['strength']}";
|
||||
$intel = "{$general['intel']}";
|
||||
}
|
||||
|
||||
|
||||
|
||||
if ($general['npc'] >= 2) {
|
||||
$name = "<font color=cyan>{$general['name']}</font>";
|
||||
} elseif ($general['npc'] == 1) {
|
||||
$name = "<font color=skyblue>{$general['name']}</font>";
|
||||
} else {
|
||||
$name = "{$general['name']}";
|
||||
}
|
||||
|
||||
if(key_exists($general['owner'], $ownerNameList)){
|
||||
$name = $name.'<br><small>('.$ownerNameList[$general['owner']].')</small>';
|
||||
}
|
||||
|
||||
$general['connect'] = Util::round($general['connect'], -1);
|
||||
|
||||
$imageTemp = GetImageURL($general['imgsvr']);
|
||||
echo "
|
||||
<tr data-general-id='{$general['no']}'
|
||||
data-general-wounded='{$general['injury']}'
|
||||
data-general-leadership='{$general['leadership']}'
|
||||
data-general-leadership-bonus='{$lbonus}'
|
||||
data-general-strength='{$general['strength']}'
|
||||
data-general-intel='{$general['intel']}'
|
||||
data-is-npc='".($general['npc']>=2?'true':'false')."'
|
||||
>
|
||||
<td align=center><img class='generalIcon' width='64' height='64' src='{$imageTemp}/{$general['picture']}'></img></td>
|
||||
<td align=center>$name</td>
|
||||
<td align=center>{$general['age']}세</td>
|
||||
<td align=center>".displayCharInfo($general['personal'])."</td>
|
||||
<td align=center>".displaySpecialDomesticInfo($general['special'])." / ".displaySpecialWarInfo($general['special2'])."</td>
|
||||
<td align=center>Lv ".getExpLevel($general['experience'])."</td>
|
||||
<td align=center>{$nation}</td>
|
||||
<td align=center>".getHonor($general['experience'])."</td>
|
||||
<td align=center>".getDed($general['dedication'])."</td>
|
||||
<td align=center>";
|
||||
echo getOfficerLevelText($general['officer_level']);
|
||||
echo "</td>
|
||||
<td align=center>$leadership</td>
|
||||
<td align=center>$strength</td>
|
||||
<td align=center>$intel</td>
|
||||
<td align=center>{$general['killturn']}</td>
|
||||
<td align=center>{$general['connect']}";
|
||||
echo "<br>【".getConnect($general['connect'])."】</td>
|
||||
</tr>";
|
||||
}
|
||||
echo "
|
||||
</table>
|
||||
";
|
||||
|
||||
?>
|
||||
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td><?=closeButton()?></td></tr>
|
||||
<tr><td><?=banner()?></td></tr>
|
||||
</table>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$("#viewType").val("<?=$type?>").attr("selected", "selected");
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
+9
-13
@@ -28,7 +28,7 @@ $scenarioList = (function(){
|
||||
|
||||
|
||||
|
||||
if($scenarioIdx !== null || key_exists($scenarioIdx, $scenarioList)){
|
||||
if($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx]??[])){
|
||||
$searchScenarioName = $scenarioList[$seasonIdx][$scenarioIdx]['name'];
|
||||
$searchFilter = $db->sqleval('season = %i AND scenario = %i', $seasonIdx, $scenarioIdx);
|
||||
}
|
||||
@@ -50,12 +50,9 @@ else{
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printCSS('css/hallOfFame.css')?>
|
||||
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery.redirect.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJs('js/hallOfFame.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJs('dist_js/hallOfFame.js')?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -64,14 +61,14 @@ else{
|
||||
<tr><td>
|
||||
시나리오 검색 : <select id="by_scenario" name="by_scenario">
|
||||
<?php foreach($scenarioList as $iterSeasonIdx=>$subScenarioList): ?>
|
||||
<option
|
||||
data-season="<?=$iterSeasonIdx?>"
|
||||
value=""
|
||||
<option
|
||||
data-season="<?=$iterSeasonIdx?>"
|
||||
value=""
|
||||
<?=($iterSeasonIdx == $seasonIdx && $scenarioIdx === null)?"selected='selected'":''?>
|
||||
>* 시즌 : <?=$iterSeasonIdx?> 종합 *</option>
|
||||
<?php foreach($subScenarioList as $info): ?>
|
||||
<option
|
||||
data-season="<?=$iterSeasonIdx?>"
|
||||
data-season="<?=$iterSeasonIdx?>"
|
||||
value="<?=$info['scenario']?>"
|
||||
<?=($iterSeasonIdx == $seasonIdx && $info['scenario']===$scenarioIdx)?"selected='selected'":''?>
|
||||
><?=$info['name']?>(<?=$info['cnt']?>회)</option>
|
||||
@@ -136,7 +133,7 @@ foreach($types as $typeName=>[$typeDescribe, $typeValue]) {
|
||||
$general['bgColor'] = $general['color'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!key_exists('fgColor', $general)){
|
||||
$general['fgColor'] = newColor($general['bgColor']);
|
||||
}
|
||||
@@ -175,4 +172,3 @@ foreach($types as $typeName=>[$typeDescribe, $typeValue]) {
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
+5
-8
@@ -99,13 +99,10 @@ $nations = Json::decode($history['nations']);
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 연감</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS("js/map/theme_{$mapTheme}.js")?>
|
||||
<?=WebUtil::printJS('js/map.js')?>
|
||||
<?=WebUtil::printJS('js/history.js')?>
|
||||
<?=WebUtil::printJS('dist_js/history.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -139,7 +136,7 @@ var nations = <?=$nations?$history['nations']:'{}'?>;
|
||||
</td></tr>
|
||||
</table>
|
||||
<table align=center width=1000 height=520 class='tb_layout bg0'>
|
||||
<thead><tr><th colspan=5 align=center id=bg1>중 원 지 도</th></tr></thead>
|
||||
<thead><tr><th colspan=5 align=center class='bg1'>중 원 지 도</th></tr></thead>
|
||||
<tbody>
|
||||
<tr height=520>
|
||||
<td width=698>
|
||||
@@ -169,13 +166,13 @@ var nations = <?=$nations?$history['nations']:'{}'?>;
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th colspan=5 align=center id=bg1>중 원 정 세</th></tr>
|
||||
<tr><th colspan=5 align=center class='bg1'>중 원 정 세</th></tr>
|
||||
<tr>
|
||||
<td colspan=5 valign=top>
|
||||
<?=formatHistoryToHTML(Json::decode($history['global_history']))?>
|
||||
</td>
|
||||
</tr>
|
||||
<tr><th colspan=5 align=center id=bg1>장 수 동 향</th></tr>
|
||||
<tr><th colspan=5 align=center class='bg1'>장 수 동 향</th></tr>
|
||||
<tr>
|
||||
<td colspan=5 valign=top>
|
||||
<?=formatHistoryToHTML(Json::decode($history['global_action']))?>
|
||||
|
||||
+13
-14
@@ -25,10 +25,9 @@ if($con >= 2) { printLimitMsg($me['turntime']); exit(); }
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 세력일람</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/ext.kingdoms.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/extKingdoms.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -48,7 +47,7 @@ $nations[0] = getNationStaticInfo(0);
|
||||
|
||||
foreach($db->query('SELECT npc,name,city,nation,officer_level,penalty,permission FROM general ORDER BY dedication DESC') as $general){
|
||||
$nationID = $general['nation'];
|
||||
|
||||
|
||||
if(!key_exists('generals', $nations[$nationID])){
|
||||
$nations[$nationID]['generals'] = [];
|
||||
}
|
||||
@@ -92,13 +91,13 @@ foreach ($nations as $nation) {
|
||||
<td colspan=8 align=center style=color:".newColor($nation['color'])."; bgcolor={$nation['color']}>【 {$nation['name']} 】</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=80 align=center id=bg1>성 향</td>
|
||||
<td width=80 align=center class='bg1'>성 향</td>
|
||||
<td width=170 align=center><font color=yellow>".getNationType($nation['type'])."</font></td>
|
||||
<td width=80 align=center id=bg1>작 위</td>
|
||||
<td width=80 align=center class='bg1'>작 위</td>
|
||||
<td width=170 align=center>".getNationLevel($nation['level'])."</td>
|
||||
<td width=80 align=center id=bg1>국 력</td>
|
||||
<td width=80 align=center class='bg1'>국 력</td>
|
||||
<td width=170 align=center>{$nation['power']}</td>
|
||||
<td width=80 align=center id=bg1>장수 / 속령</td>
|
||||
<td width=80 align=center class='bg1'>장수 / 속령</td>
|
||||
<td width=170 align=center>{$nation['gennum']} / ".count($nation['cities']??[])."</td>
|
||||
";
|
||||
for($chiefLevel = 12; $chiefLevel >= 5; $chiefLevel--){
|
||||
@@ -113,9 +112,9 @@ foreach ($nations as $nation) {
|
||||
}
|
||||
echo "</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>외교권자</td><td colspan=5>";
|
||||
<td align=center class='bg1'>외교권자</td><td colspan=5>";
|
||||
echo join(', ', $ambassadors);
|
||||
echo "</td><td align=center id=bg1>조언자</td><td align=center >";
|
||||
echo "</td><td align=center class='bg1'>조언자</td><td align=center >";
|
||||
echo count($auditors).'명';
|
||||
echo "</td></tr>
|
||||
<tr>
|
||||
@@ -160,9 +159,9 @@ echo "
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=498 align=center> </td>
|
||||
<td width=123 align=center id=bg1>장 수</td>
|
||||
<td width=123 align=center class='bg1'>장 수</td>
|
||||
<td width=123 align=center>{$nations[0]['gennum']}</td>
|
||||
<td width=123 align=center id=bg1>속 령</td>
|
||||
<td width=123 align=center class='bg1'>속 령</td>
|
||||
<td width=123 align=center>".count($nations[0]['cities']??[])."</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -177,7 +176,7 @@ echo"
|
||||
<td colspan=5> 장수 일람 : ";
|
||||
foreach($nations[0]['generals'] as $general) {
|
||||
$generalText = getColoredName($general['name'], $general['npc']);
|
||||
echo "{$generalText}, ";
|
||||
echo "{$generalText}, ";
|
||||
}
|
||||
echo"
|
||||
</td>
|
||||
|
||||
+21
-16
@@ -26,9 +26,9 @@ $sel[$type] = "selected";
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 빙의일람</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -59,8 +59,13 @@ foreach (getAllNationStaticInfo() as $nation) {
|
||||
$nationName[$nation['nation']] = $nation['name'];
|
||||
}
|
||||
|
||||
|
||||
$generalList = $db->query('SELECT npc,nation,name,owner_name,special,special2,personal,leadership,strength,intel,leadership+strength+intel as sum,explevel,experience,dedication from general where npc=1');
|
||||
$generalListFromPool = $db->query('SELECT npc,nation,name,owner_name,special,special2,personal,leadership,strength,intel,leadership+strength+intel as sum,explevel,experience,dedication from general JOIN select_pool on general.no = select_pool.general_id where npc=0');
|
||||
|
||||
if($generalListFromPool){
|
||||
$generalList = array_merge($generalListFromPool, $generalList);
|
||||
}
|
||||
|
||||
$sortType = [
|
||||
1 => ['name', true],
|
||||
2 => ['nation', true],
|
||||
@@ -88,18 +93,18 @@ else{
|
||||
?>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=102 align=center id=bg1>희생된 장수</td>
|
||||
<td width=102 align=center id=bg1>악령 이름</td>
|
||||
<td width=68 align=center id=bg1>레벨</td>
|
||||
<td width=118 align=center id=bg1>국가</td>
|
||||
<td width=68 align=center id=bg1>성격</td>
|
||||
<td width=88 align=center id=bg1>특기</td>
|
||||
<td width=68 align=center id=bg1>종능</td>
|
||||
<td width=68 align=center id=bg1>통솔</td>
|
||||
<td width=68 align=center id=bg1>무력</td>
|
||||
<td width=68 align=center id=bg1>지력</td>
|
||||
<td width=78 align=center id=bg1>명성</td>
|
||||
<td width=78 align=center id=bg1>계급</td>
|
||||
<td width=102 align=center class='bg1'>희생된 장수</td>
|
||||
<td width=102 align=center class='bg1'>악령 이름</td>
|
||||
<td width=68 align=center class='bg1'>레벨</td>
|
||||
<td width=118 align=center class='bg1'>국가</td>
|
||||
<td width=68 align=center class='bg1'>성격</td>
|
||||
<td width=88 align=center class='bg1'>특기</td>
|
||||
<td width=68 align=center class='bg1'>종능</td>
|
||||
<td width=68 align=center class='bg1'>통솔</td>
|
||||
<td width=68 align=center class='bg1'>무력</td>
|
||||
<td width=68 align=center class='bg1'>지력</td>
|
||||
<td width=78 align=center class='bg1'>명성</td>
|
||||
<td width=78 align=center class='bg1'>계급</td>
|
||||
</tr>
|
||||
<?php foreach($generalList as $general): ?>
|
||||
<tr>
|
||||
|
||||
+3
-5
@@ -27,12 +27,11 @@ if($con >= 2) { printLimitMsg($me['turntime']); exit(); }
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 세력도</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printJS('d_shared/base_map.js')?>
|
||||
<?=WebUtil::printJS('js/map.js')?>
|
||||
<?=WebUtil::printJS('dist_js/map.js')?>
|
||||
<script>
|
||||
window.serverNick = '<?=DB::prefix()?>';
|
||||
window.serverID = '<?=UniqueConst::$serverID?>';
|
||||
@@ -80,4 +79,3 @@ $(function(){
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
+16
-16
@@ -52,9 +52,9 @@ if ($admin['maxonline'] < $curonline) {
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -92,7 +92,7 @@ span.out_bar{
|
||||
<table align=center width=1016>
|
||||
<tr><td align=left>
|
||||
<table align=center class='tb_layout bg0'>
|
||||
<tr><td colspan=4 align=center id=bg2><font size=5>접 속 량</font></td></tr>
|
||||
<tr><td colspan=4 align=center class='bg2'><font size=5>접 속 량</font></td></tr>
|
||||
<?php
|
||||
$refresh[] = $admin['refresh'];
|
||||
foreach($refresh as $i=>$value){
|
||||
@@ -101,8 +101,8 @@ foreach($refresh as $i=>$value){
|
||||
$dt = substr($date[$i], 11, 5); ?>
|
||||
<tr height=30>
|
||||
<td width=100 align=center><?=$year[$i]?>년 <?=$month[$i]?>월</td>
|
||||
<td width=60 align=center id=bg2><?=$dt?></td>
|
||||
<td width=2 align=center id=bg1></td>
|
||||
<td width=60 align=center class='bg2'><?=$dt?></td>
|
||||
<td width=2 align=center class='bg1'></td>
|
||||
<td width=320>
|
||||
<?php if($w == 0): ?>
|
||||
<span class="out_bar"><?=$value?></span>
|
||||
@@ -111,15 +111,15 @@ foreach($refresh as $i=>$value){
|
||||
<?php else:?>
|
||||
<div class='big_bar' style='width:<?=$w?>%;background-color:<?=$color?>;'><span><?=$value?></span></div>
|
||||
<?php endif;?>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<tr><td colspan=4 height=5 align=center id=bg1></td></tr>
|
||||
<tr><td colspan=4 height=5 align=center class='bg1'></td></tr>
|
||||
<tr>
|
||||
<td colspan=4 height=30 align=center id=bg0>최고기록: <?=$admin['maxrefresh']?></td>
|
||||
<td colspan=4 height=30 align=center class='bg0'>최고기록: <?=$admin['maxrefresh']?></td>
|
||||
</tr>
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ foreach($refresh as $i=>$value){
|
||||
</td>
|
||||
<td align=right>
|
||||
<table align=center class='tb_layout bg0'>
|
||||
<tr><td colspan=4 align=center id=bg2><font size=5>접 속 자</font></td></tr>
|
||||
<tr><td colspan=4 align=center class='bg2'><font size=5>접 속 자</font></td></tr>
|
||||
<?php
|
||||
$online[] = $curonline;
|
||||
foreach($online as $i=>$value){
|
||||
@@ -136,8 +136,8 @@ foreach($online as $i=>$value){
|
||||
$dt = substr($date[$i], 11, 5); ?>
|
||||
<tr height=30>
|
||||
<td width=100 align=center><?=$year[$i]?>년 <?=$month[$i]?>월</td>
|
||||
<td width=60 align=center id=bg2><?=$dt?></td>
|
||||
<td width=2 align=center id=bg1></td>
|
||||
<td width=60 align=center class='bg2'><?=$dt?></td>
|
||||
<td width=2 align=center class='bg1'></td>
|
||||
<td width=320>
|
||||
<?php if($w == 0): ?>
|
||||
<span class="out_bar"><?=$value?></span>
|
||||
@@ -146,22 +146,22 @@ foreach($online as $i=>$value){
|
||||
<?php else:?>
|
||||
<div class='big_bar' style='width:<?=$w?>%;background-color:<?=$color?>;'><span><?=$value?></span></div>
|
||||
<?php endif;?>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<tr><td colspan=4 height=5 align=center id=bg1></td></tr>
|
||||
<tr><td colspan=4 height=5 align=center class='bg1'></td></tr>
|
||||
<tr>
|
||||
<td colspan=4 height=30 align=center id=bg0>최고기록: <?=$admin['maxonline']?></td>
|
||||
<td colspan=4 height=30 align=center class='bg0'>최고기록: <?=$admin['maxonline']?></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
<br>
|
||||
<table align=center class='tb_layout bg0'>
|
||||
<tr><td colspan=3 align=center id=bg2><font size=5>주 의 대 상 자 (순간과도갱신)</font></td></tr>
|
||||
<tr><td colspan=3 align=center class='bg2'><font size=5>주 의 대 상 자 (순간과도갱신)</font></td></tr>
|
||||
<?php
|
||||
$max_refresh = $db->queryFirstRow('SELECT sum(refresh) as refresh, sum(`connect`) as `connect` from general');
|
||||
$max_refresh['name'] = '접속자 총합';
|
||||
|
||||
+13
-13
@@ -12,7 +12,7 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
increaseRefresh("설문조사", 1);
|
||||
|
||||
$isVoteAdmin = in_array('vote', $session->acl[DB::prefix()]??[]);
|
||||
$isVoteAdmin |= $session->userGrade >= 5;
|
||||
$isVoteAdmin = $isVoteAdmin || $session->userGrade >= 5;
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no,vote from general where owner=%i', $userID);
|
||||
|
||||
@@ -28,9 +28,9 @@ $vote = $admin['vote']?:['-'];
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -60,7 +60,7 @@ function captureKey(e) {
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<form name=form1 action=c_vote.php method=post>
|
||||
<tr><td colspan=3 align=center id=bg2><font size=5>설 문 조 사 (<?=$admin['develcost']*5?>금과 추첨으로 유니크템 증정!)</font></td></tr>
|
||||
<tr><td colspan=3 align=center class='bg2'><font size=5>설 문 조 사 (<?=$admin['develcost']*5?>금과 추첨으로 유니크템 증정!)</font></td></tr>
|
||||
<?php
|
||||
|
||||
if ($isVoteAdmin) {
|
||||
@@ -76,7 +76,7 @@ if ($isVoteAdmin) {
|
||||
$vote_title = Tag2Code($vote_title);
|
||||
echo "
|
||||
<tr>
|
||||
<td colspan=2 width=148 align=center id=bg1>제 목</td>
|
||||
<td colspan=2 width=148 align=center class='bg1'>제 목</td>
|
||||
<td width=848 align=left> {$vote_title}</td>
|
||||
</tr>
|
||||
";
|
||||
@@ -151,7 +151,7 @@ echo "
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td colspan=4 align=center id=bg1>댓 글</td>
|
||||
<td colspan=4 align=center class='bg1'>댓 글</td>
|
||||
</tr>
|
||||
";
|
||||
for ($i=0; $i < $commentCount; $i++) {
|
||||
@@ -180,7 +180,7 @@ if ($me['no'] > 0) {
|
||||
</table>
|
||||
<br>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td colspan=3 align=center id=bg2><font size=5>
|
||||
<tr><td colspan=3 align=center class='bg2'><font size=5>
|
||||
전 체 통 계
|
||||
<?php
|
||||
if ($isVoteAdmin) {
|
||||
@@ -238,8 +238,8 @@ if ($admin['voteopen'] >= 1 || $isVoteAdmin) {
|
||||
else{
|
||||
$totalPer += $per;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// if($per < 5) { $vote['cnt'] = " "; }
|
||||
?>
|
||||
<?php if($per == 0): ?>
|
||||
@@ -303,7 +303,7 @@ if ($admin['voteopen'] >= 2 || $isVoteAdmin) {
|
||||
foreach($db->query('SELECT nation,color,name,gennum from nation order by gennum desc') as $i=>$nation){
|
||||
$memCount = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=%i AND npc<2', $nation['nation']);
|
||||
|
||||
|
||||
|
||||
|
||||
$voteCount = $nationVoteCount[$nation['nation']] ?? 0;
|
||||
if($memCount == 0){
|
||||
@@ -312,7 +312,7 @@ if ($admin['voteopen'] >= 2 || $isVoteAdmin) {
|
||||
else{
|
||||
$percentage = round($voteCount / $memCount * 100, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
echo "
|
||||
<tr>
|
||||
@@ -336,7 +336,7 @@ if ($admin['voteopen'] >= 2 || $isVoteAdmin) {
|
||||
else{
|
||||
$totalPer += $per;
|
||||
}
|
||||
|
||||
|
||||
// if($per < 5) { $vote['cnt'] = " "; }
|
||||
?>
|
||||
<?php if($per == 0): ?>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
APIHelper::launch(dirname(__FILE__));
|
||||
+14
-14
@@ -49,9 +49,9 @@ if ($msg2 == "") {
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -59,12 +59,12 @@ if ($msg2 == "") {
|
||||
<body>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td>거 래 장<br><?=closeButton()?></td></tr>
|
||||
<tr><td align=center id=bg2><font color=orange size=6><b>거 래 장</b></font><input type=button value='갱신' onclick="location.replace('b_auction.php')"></td></tr>
|
||||
<tr><td align=center class='bg2'><font color=orange size=6><b>거 래 장</b></font><input type=button value='갱신' onclick="location.replace('b_auction.php')"></td></tr>
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<form method=post action=c_auction.php>
|
||||
<tr><td colspan=11 align=center bgcolor=orange><font size=5>팝 니 다</font></td></tr>
|
||||
<tr align=center id=bg1>
|
||||
<tr align=center class='bg1'>
|
||||
<td width=68>거래번호</td>
|
||||
<td width=48>선택</td>
|
||||
<td width=98>판매자</td>
|
||||
@@ -118,18 +118,18 @@ foreach($db->query('SELECT * from auction where type=0 order by expire') as $auc
|
||||
}
|
||||
?>
|
||||
<tr height=25>
|
||||
<td align=center id=bg1>등록결과</td>
|
||||
<td align=center class='bg1'>등록결과</td>
|
||||
<td colspan=10><?=ConvertLog($msg)?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>입찰등록</td>
|
||||
<td align=center class='bg1'>입찰등록</td>
|
||||
<td colspan=10>
|
||||
지불할 금액: <input type=text style=color:white;background-color:black; size=6 maxlength=6 name=value>
|
||||
<input type=<?=$btn?> name=btn value='구매시도' onclick='return confirm("정말 입찰하시겠습니까?");'>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>거래등록</td>
|
||||
<td align=center class='bg1'>거래등록</td>
|
||||
<td colspan=10>
|
||||
종료: <input type=text style=color:white;background-color:black; size=2 maxlength=2 name=term value=12>턴 후
|
||||
물품: 쌀
|
||||
@@ -152,7 +152,7 @@ foreach($db->query('SELECT * from auction where type=0 order by expire') as $auc
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<form method=post action=c_auction.php>
|
||||
<tr><td colspan=11 align=center bgcolor=skyblue><font size=5>삽 니 다</font></td></tr>
|
||||
<tr align=center id=bg1>
|
||||
<tr align=center class='bg1'>
|
||||
<td width=68>거래번호</td>
|
||||
<td width=48>선택</td>
|
||||
<td width=98>구매자</td>
|
||||
@@ -205,18 +205,18 @@ foreach($db->query('SELECT * from auction where type=1 order by expire') as $auc
|
||||
}
|
||||
?>
|
||||
<tr height=25>
|
||||
<td align=center id=bg1>등록결과</td>
|
||||
<td align=center class='bg1'>등록결과</td>
|
||||
<td colspan=10><?=ConvertLog($msg2)?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>입찰등록</td>
|
||||
<td align=center class='bg1'>입찰등록</td>
|
||||
<td colspan=10>
|
||||
수령할 금액: <input type=text style=color:white;background-color:black; size=6 maxlength=6 name=value>
|
||||
<input type=<?=$btn?> name=btn value='판매시도' onclick='return confirm("정말 입찰하시겠습니까?");'>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>거래등록</td>
|
||||
<td align=center class='bg1'>거래등록</td>
|
||||
<td colspan=10>
|
||||
종료: <input type=text style=color:white;background-color:black; size=2 maxlength=2 name=term value=12>턴 후
|
||||
물품: 쌀
|
||||
@@ -237,11 +237,11 @@ foreach($db->query('SELECT * from auction where type=1 order by expire') as $auc
|
||||
</table>
|
||||
<br>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td align=center id=bg2><font size=5>최 근 기 록</font></td></tr>
|
||||
<tr><td align=center class='bg2'><font size=5>최 근 기 록</font></td></tr>
|
||||
<tr><td>
|
||||
<?=getAuctionLogRecent(20)?>
|
||||
</td></tr>
|
||||
<tr><td align=center id=bg2><font size=5>도 움 말</font></td></tr>
|
||||
<tr><td align=center class='bg2'><font size=5>도 움 말</font></td></tr>
|
||||
<tr><td>
|
||||
<font color=white size=2>
|
||||
ㆍ판매거래는 거래자가 판매할 물품을 거래하면, 구입을 희망하는 사람이 현재가보다 높게 입찰하여 구입하는 방식입니다.<br>
|
||||
|
||||
+13
-13
@@ -87,10 +87,10 @@ else if($reqArgType===1){
|
||||
$generalBasicList = $db->query('SELECT no, name, npc, turntime, officer_level, %b FROM general WHERE nation = %i', $reqQueryType, $nationID);
|
||||
}
|
||||
else if($reqArgType===2){
|
||||
$generalBasicList = $db->query('SELECT no, name, npc, turntime, officer_level, value as %b
|
||||
FROM general LEFT JOIN rank_data
|
||||
ON general.no = rank_data.general_id
|
||||
WHERE rank_data.type = %s AND general.nation = %i',
|
||||
$generalBasicList = $db->query('SELECT no, name, npc, turntime, officer_level, value as %b
|
||||
FROM general LEFT JOIN rank_data
|
||||
ON general.no = rank_data.general_id
|
||||
WHERE rank_data.type = %s AND general.nation = %i',
|
||||
$reqQueryType, $reqQueryType, $nationID
|
||||
);
|
||||
}
|
||||
@@ -120,9 +120,9 @@ $showGeneral = General::createGeneralObjFromDB($gen);
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -153,8 +153,8 @@ $showGeneral = General::createGeneralObjFromDB($gen);
|
||||
</table>
|
||||
<table width=1000 align=center class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=50% align=center id=bg1><font color=skyblue size=3>장 수 정 보</font></td>
|
||||
<td width=50% align=center id=bg1><font color=orange size=3>장 수 열 전</font></td>
|
||||
<td width=50% align=center class='bg1'><font color=skyblue size=3>장 수 정 보</font></td>
|
||||
<td width=50% align=center class='bg1'><font color=orange size=3>장 수 열 전</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
@@ -165,8 +165,8 @@ $showGeneral = General::createGeneralObjFromDB($gen);
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1><font color=orange size=3>전투 기록</font></td>
|
||||
<td align=center id=bg1><font color=orange size=3>전투 결과</font></td>
|
||||
<td align=center class='bg1'><font color=orange size=3>전투 기록</font></td>
|
||||
<td align=center class='bg1'><font color=orange size=3>전투 결과</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
@@ -178,8 +178,8 @@ $showGeneral = General::createGeneralObjFromDB($gen);
|
||||
</tr>
|
||||
<?php if($showGeneral->getNPCType() > 1 || $permission >= 2): ?>
|
||||
<tr>
|
||||
<td align=center id=bg1><font color=orange size=3>개인 기록</font></td>
|
||||
<td align=center id=bg1><font color=orange size=3> </font></td>
|
||||
<td align=center class='bg1'><font color=orange size=3>개인 기록</font></td>
|
||||
<td align=center class='bg1'><font color=orange size=3> </font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
|
||||
+10
-11
@@ -63,10 +63,9 @@ if($str3){
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 베팅장</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/betting.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/betting.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -79,7 +78,7 @@ if($str3){
|
||||
<table align=center width=1120 class='tb_layout bg0'>
|
||||
<tr><td colspan=16><input type=button value='갱신' onclick='location.reload()'></td></tr>
|
||||
<tr><td colspan=16 align=center><font color=white size=6><?=$tnmt_type?> (<?=$str1.$str2.$str3?>)</font></td></tr>
|
||||
<tr><td height=50 colspan=16 align=center id=bg2><font color=limegreen size=6>16강 상황</font><br><font color=orange size=3>(전체 금액 : <?=$globalBetTotal?> / 내 투자 금액 : <?=$myBetTotal?>)</font></td></tr>
|
||||
<tr><td height=50 colspan=16 align=center class='bg2'><font color=limegreen size=6>16강 상황</font><br><font color=orange size=3>(전체 금액 : <?=$globalBetTotal?> / 내 투자 금액 : <?=$myBetTotal?>)</font></td></tr>
|
||||
</table>
|
||||
<table align=center width=1120 class='mimic_flex bg0' style='border:solid 1px gray;font-size:10px;'>
|
||||
<tr align=center><td height=10 colspan=16></td></tr>
|
||||
@@ -311,7 +310,7 @@ for ($i=0; $i < 16; $i++) {
|
||||
else{
|
||||
$gold[$i] = Util::round($myBet[$i] * $bet[$i]);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
?>
|
||||
</tr>
|
||||
@@ -393,8 +392,8 @@ if ($admin['tournament'] == 6) {
|
||||
<tr align=center><td height=10 colspan=16></td></tr>
|
||||
</table>
|
||||
<table align=center width=1120 class='tb_layout bg0'>
|
||||
<tr align=center><td height=50 colspan=4 id=bg2><font color=yellow size=6>토너먼트 랭킹</font></td></tr>
|
||||
<tr align=center><td colspan=4 id=bg2><font color=skyblue size=3>순위 / 장수명 / 능력치 / 경기수 / 승리 / 무승부 / 패배 / 집계점수 / 우승횟수</font></td></tr>
|
||||
<tr align=center><td height=50 colspan=4 class='bg2'><font color=yellow size=6>토너먼트 랭킹</font></td></tr>
|
||||
<tr align=center><td colspan=4 class='bg2'><font color=skyblue size=3>순위 / 장수명 / 능력치 / 경기수 / 승리 / 무승부 / 패배 / 집계점수 / 우승횟수</font></td></tr>
|
||||
<tr align=center>
|
||||
<?php
|
||||
|
||||
@@ -430,7 +429,7 @@ foreach($tournamentType as $tournamentTypeText=>[$statTypeText,$statFunc,$rankCo
|
||||
<td>
|
||||
<table align=center width=280 class='tb_layout bg0'>
|
||||
<tr><td colspan=9 align=center style=color:white;background-color:black;><font size=4><?=$tournamentTypeText?></font></td></tr>
|
||||
<tr id=bg1><td align=center>순</td><td align=center>장수</td><td align=center><?=$statTypeText?></td><td align=center>경</td><td align=center>승</td><td align=center>무</td><td align=center>패</td><td align=center>점</td><td align=center>勝</td></tr>
|
||||
<tr class='bg1'><td align=center>순</td><td align=center>장수</td><td align=center><?=$statTypeText?></td><td align=center>경</td><td align=center>승</td><td align=center>무</td><td align=center>패</td><td align=center>점</td><td align=center>勝</td></tr>
|
||||
<?php
|
||||
$prizeColumn = "{$rankColumn}p";
|
||||
$gameColumn = "{$rankColumn}g";
|
||||
@@ -446,8 +445,8 @@ foreach($tournamentType as $tournamentTypeText=>[$statTypeText,$statFunc,$rankCo
|
||||
$result = -($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn));
|
||||
if($result !== 0) return $result;
|
||||
$result = -(
|
||||
($lhs->getRankVar($winColumn)+$lhs->getRankVar($drawColumn)+$lhs->getRankVar($loseColumn))
|
||||
<=>
|
||||
($lhs->getRankVar($winColumn)+$lhs->getRankVar($drawColumn)+$lhs->getRankVar($loseColumn))
|
||||
<=>
|
||||
($rhs->getRankVar($winColumn)+$rhs->getRankVar($drawColumn)+$rhs->getRankVar($loseColumn))
|
||||
);
|
||||
if($result !== 0) return $result;
|
||||
|
||||
@@ -15,12 +15,9 @@ $generalObj = General::createGeneralObjFromDB($session->generalID);
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 사령부</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery.redirect.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/moment.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/chiefCenter.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/chiefCenter.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -108,4 +105,3 @@ var maxChiefTurn = <?=GameConst::$maxChiefTurn?>;
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
+79
-24
@@ -16,7 +16,11 @@ $db = DB::db();
|
||||
increaseRefresh("현재도시", 1);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no,nation,officer_level,city from general where owner=%i', $userID);
|
||||
$myNation = $db->queryFirstRow('SELECT nation,level,spy FROM nation WHERE nation=%i', $me['nation']);
|
||||
$myNation = $db->queryFirstRow('SELECT nation,level,spy FROM nation WHERE nation=%i', $me['nation'])??[
|
||||
'nation'=>0,
|
||||
'level'=>0,
|
||||
'spy'=>''
|
||||
];
|
||||
|
||||
$templates = new \League\Plates\Engine('templates');
|
||||
|
||||
@@ -29,11 +33,9 @@ $templates = new \League\Plates\Engine('templates');
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/select2/select2.full.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/currentCity.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/currentCity.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/select2/select2.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/select2/select2-bootstrap4.css')?>
|
||||
@@ -148,8 +150,31 @@ echo "
|
||||
unset($city);
|
||||
|
||||
// 첩보된 도시까지만 허용
|
||||
if($valid == 0 && $userGrade < 5) {
|
||||
|
||||
$showDetailedInfo = false;
|
||||
if($valid){
|
||||
$showDetailedInfo = true;
|
||||
}
|
||||
|
||||
if(!key_exists($citylist, CityConst::all())){
|
||||
$citylist = $me['city'];
|
||||
$showDetailedInfo = true;
|
||||
$valid = 1;
|
||||
}
|
||||
|
||||
if($userGrade >= 5){
|
||||
$valid = true;
|
||||
$showDetailedInfo = true;
|
||||
}
|
||||
|
||||
if(!$valid) {
|
||||
$ownCities = Util::convertArrayToSetLike($db->queryFirstColumn('SELECT city FROM city WHERE nation = %i AND nation != 0', $me['nation']));
|
||||
foreach(array_keys(CityConst::byID($citylist)->path) as $pathID){
|
||||
if(key_exists($pathID, $ownCities)){
|
||||
$showDetailedInfo = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -172,17 +197,41 @@ if($city['trade'] === null) {
|
||||
}
|
||||
|
||||
$dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'], 2)[0];
|
||||
$generals = $db->query(
|
||||
'SELECT %l from general where city=%i order by name',
|
||||
Util::formatListOfBackticks($dbColumns),
|
||||
$city['city']
|
||||
);
|
||||
if($showDetailedInfo){
|
||||
$generals = $db->query(
|
||||
'SELECT %l from general where city=%i order by turntime',
|
||||
Util::formatListOfBackticks($dbColumns),
|
||||
$city['city']
|
||||
);
|
||||
}
|
||||
else{
|
||||
$generals = [];
|
||||
}
|
||||
|
||||
if($valid){
|
||||
$city['trustText'] = round($city['trust'], 1);
|
||||
$city['popRateText'] = round($city['pop']/$city['pop_max']*100, 2);
|
||||
}
|
||||
else{
|
||||
$city['agri'] = '?';
|
||||
$city['comm'] = '?';
|
||||
$city['pop'] = '?';
|
||||
$city['secu'] = '?';
|
||||
$city['trustText'] = '?';
|
||||
$city['popRateText'] = '?';
|
||||
|
||||
if($city['nation'] != 0){
|
||||
$city['def'] = '?';
|
||||
$city['wall'] = '?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$generalTurnList = [];
|
||||
|
||||
if($generals){
|
||||
foreach($db->queryAllLists(
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
array_column($generals, 'no')
|
||||
) as [$generalID, $turnIdx, $brief]
|
||||
){
|
||||
@@ -221,7 +270,7 @@ foreach($generals as $general){
|
||||
|
||||
$isNPC = $general['npc']>1;
|
||||
$wounded = $general['injury'];
|
||||
|
||||
|
||||
|
||||
$name = $general['name'];
|
||||
$nameText = formatName($name, $general['npc']);
|
||||
@@ -257,6 +306,10 @@ foreach($generals as $general){
|
||||
$crew = $general['crew'];
|
||||
$train = -1;
|
||||
$atmos = -1;
|
||||
|
||||
if(!$valid){
|
||||
$crew = -1;
|
||||
}
|
||||
}
|
||||
|
||||
$nation = $general['nation'];
|
||||
@@ -274,7 +327,7 @@ foreach($generals as $general){
|
||||
else{
|
||||
$turnText = '';
|
||||
}
|
||||
|
||||
|
||||
$generalsFormat[] = [
|
||||
'ourGeneral'=>$ourGeneral,
|
||||
'iconPath'=>GetImageURL($general['imgsvr']).'/'.$general['picture'],
|
||||
@@ -326,12 +379,14 @@ $genTotal = 0;
|
||||
|
||||
|
||||
foreach($generalsFormat as $general){
|
||||
if($general['nation'] == 0){
|
||||
if(!$general['nation'] || !$myNation['nation']){
|
||||
continue;
|
||||
}
|
||||
if($general['nation'] != $myNation['nation']){
|
||||
$enemyCnt += 1;
|
||||
$enemyCrew += $general['crew'];
|
||||
if($general['crew'] >= 0){
|
||||
$enemyCrew += $general['crew'];
|
||||
}
|
||||
if($general['crew'] > 0){
|
||||
$enemyArmedCnt += 1;
|
||||
}
|
||||
@@ -354,7 +409,7 @@ foreach($generalsFormat as $general){
|
||||
}
|
||||
|
||||
$chkDef = false;
|
||||
|
||||
|
||||
if($minTrain >= 80){
|
||||
$crew80 += $general['crew'];
|
||||
$gen80 += 1;
|
||||
@@ -371,7 +426,7 @@ foreach($generalsFormat as $general){
|
||||
$chkDef = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -402,11 +457,11 @@ foreach($generalsFormat as $general){
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center class=bg1>민심</td>
|
||||
<td align=center><?=round($city['trust'], 1)?></td>
|
||||
<td align=center><?=$city['trustText']?></td>
|
||||
<td align=center class=bg1>시세</td>
|
||||
<td align=center><?=$city['trade']?>%</td>
|
||||
<td align=center class=bg1>인구</td>
|
||||
<td align=center><?=round($city['pop']/$city['pop_max']*100, 2)?>%</td>
|
||||
<td align=center><?=$city['popRateText']?>%</td>
|
||||
<td align=center class=bg1>태수</td>
|
||||
<td align=center><?=$officer[4]['name']?></td>
|
||||
<td align=center class=bg1>군사</td>
|
||||
@@ -430,11 +485,12 @@ foreach($generalsFormat as $general){
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center class=bg1>장수</td>
|
||||
<td colspan=11><?=join(', ', $generalsName)?></td>
|
||||
<td colspan=11><?=$showDetailedInfo?join(', ', $generalsName):'<span style="color:gray">알 수 없음</span>'?></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<br>
|
||||
<?php if($showDetailedInfo): ?>
|
||||
<table align=center class='tb_layout bg0'>
|
||||
<thead>
|
||||
<tr>
|
||||
@@ -459,11 +515,10 @@ foreach($generalsFormat as $general){
|
||||
?>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<?php endif; ?>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td><?=backButton()?></td></tr>
|
||||
<tr><td><?=banner()?> </td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
+11
-14
@@ -55,20 +55,17 @@ $nationStor->cacheValues(['notice', 'scout_msg']);
|
||||
<title><?=UniqueConst::$serverName?>: 내무부</title>
|
||||
<script>
|
||||
var editable = <?=(($me['officer_level']>=5||$permission==4)?'true':'false')?>;
|
||||
var nationMsg = <?=Json::encode($nationStor->notice??'')?>;
|
||||
var scoutmsg = <?=Json::encode($nationStor->scout_msg??'')?>;
|
||||
var storedData = <?=Json::encode([
|
||||
"nationMsg"=>$nationStor->notice??'',
|
||||
"scoutMsg"=>$nationStor->scout_msg??''
|
||||
])?>;
|
||||
</script>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/summernote/summernote-bs4.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/summernote/lang/summernote-ko-KR.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/summernote/plugin/image-sammo/summernote-image-flip.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/dipcenter.js')?>
|
||||
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/dipcenter.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/summernote/summernote-bs4.css')?>
|
||||
<?=WebUtil::printCSS('dist_css/vendors.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printCSS('css/dipcenter.css')?>
|
||||
@@ -116,14 +113,14 @@ foreach($nationsList as $staticNation):
|
||||
0 => "<font color=red>교 전</font>",
|
||||
1 => "<font color=magenta>선포중</font>",
|
||||
2 => "통 상",
|
||||
7 => "<font color=green>불가침</font>",
|
||||
7 => "<font color=green>불가침</font>",
|
||||
][$diplomacyState['state']];
|
||||
|
||||
if($diplomacyState['term']){
|
||||
$dipEndMonth = $admin['month'] + $diplomacyState['term'] - 1;
|
||||
$dipEndYear = $admin['year'] + intdiv($dipEndMonth, 12);
|
||||
$dipEndMonth = $dipEndMonth % 12 + 1;
|
||||
|
||||
|
||||
$dipTermText = $diplomacyState['term'].'개월';
|
||||
$dipEndDateText = "{$dipEndYear}年 {$dipEndMonth}月";
|
||||
}
|
||||
@@ -200,12 +197,12 @@ if ($budgetricediff > 0) {
|
||||
</div>
|
||||
</div>
|
||||
<div style='border-bottom:solid gray 0.5px;'>870px x 200px를 넘어서는 내용은 표시되지 않습니다.</div>
|
||||
<input type='hidden' class='input_form' name='scoutmsg' data-global='scoutmsg'>
|
||||
<input type='hidden' class='input_form' name='scoutMsg' data-global='scoutMsg'>
|
||||
<div style="width:870px;margin-left:auto;">
|
||||
<div class='edit_form viewer'></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div></td></tr>
|
||||
<tr><td colspan=2 align=center bgcolor=green>예 산 & 정 책</td></tr>
|
||||
<tr>
|
||||
|
||||
+11
-12
@@ -31,8 +31,8 @@ foreach($db->queryAllLists('SELECT nation, count(city) FROM city WHERE nation !=
|
||||
|
||||
$realConflict = [];
|
||||
foreach ($db->queryAllLists('SELECT city, `name`, conflict FROM city WHERE conflict!=%s', '{}') as [
|
||||
$cityID,
|
||||
$cityName,
|
||||
$cityID,
|
||||
$cityName,
|
||||
$rawConflict
|
||||
])
|
||||
{
|
||||
@@ -62,7 +62,7 @@ foreach($db->queryAllLists('SELECT me, you, state FROM diplomacy') as [$me, $you
|
||||
if(!key_exists($me, $diplomacyList)){
|
||||
$diplomacyList[$me] = [];
|
||||
}
|
||||
|
||||
|
||||
$diplomacyList[$me][$you] = $state;
|
||||
}
|
||||
|
||||
@@ -90,12 +90,11 @@ $neutralStateCharMap = [
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 중원 정보</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printJS('d_shared/base_map.js')?>
|
||||
<?=WebUtil::printJS('js/map.js')?>
|
||||
<?=WebUtil::printJS('dist_js/map.js')?>
|
||||
<script>
|
||||
window.serverNick = '<?=DB::prefix()?>';
|
||||
window.serverID = '<?=UniqueConst::$serverID?>';
|
||||
@@ -163,9 +162,9 @@ else{
|
||||
<table class='tb_layout bg0' style='width:100%;'>
|
||||
<?php foreach($conflict as $item): ?>
|
||||
<tr>
|
||||
<td
|
||||
<td
|
||||
width=130
|
||||
align=right
|
||||
align=right
|
||||
style='color:<?=newColor($item['color'])?>;background-color:<?=$item['color']?>;'
|
||||
><?=$item['name']?> </td>
|
||||
<td width=48 align=right><?=(float)$item['percent']?> % </td>
|
||||
@@ -175,14 +174,14 @@ else{
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<?php endforeach; ?>
|
||||
<tr><td colspan=2 height=5 id=bg1></td></tr>
|
||||
<tr><td colspan=2 height=5 class='bg1'></td></tr>
|
||||
</table>
|
||||
|
||||
<?php endif; ?>
|
||||
<?php endif; ?>
|
||||
|
||||
<br>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
|
||||
+5
-5
@@ -56,9 +56,9 @@ $templates = new \League\Plates\Engine('templates');
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@@ -105,7 +105,7 @@ $generals = $db->query(
|
||||
$generalTurnList = [];
|
||||
|
||||
foreach($db->queryAllLists(
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
array_column($generals, 'no')
|
||||
) as [$generalID, $turnIdx, $brief]
|
||||
){
|
||||
@@ -157,7 +157,7 @@ foreach ($generals as &$general) {
|
||||
$general['modeText'] = formatDefenceTrain($general['defence_train']);
|
||||
$general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name??'-';
|
||||
|
||||
|
||||
|
||||
if ($general['npc'] < 2) {
|
||||
$turntext = [];
|
||||
foreach($generalTurnList[$general['no']] as $turnRawIdx=>$turn){
|
||||
|
||||
+32
-33
@@ -33,11 +33,10 @@ $nation = $db->queryFirstRow('SELECT nation,name,level,color,chief_set from nati
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 인사부</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/select2/select2.full.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/bossInfo.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printJS('dist_js/bossInfo.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/select2/select2.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/select2/select2-bootstrap4.css')?>
|
||||
@@ -48,7 +47,7 @@ var chiefStatMin = <?=GameConst::$chiefStatMin?>;
|
||||
var myLevel = <?=$meLevel?>;
|
||||
</script>
|
||||
|
||||
<?php
|
||||
<?php
|
||||
|
||||
$ambassadors = $db->query('SELECT no, name, officer_level, penalty, permission FROM general WHERE permission = \'ambassador\' AND nation = %i', $nationID);
|
||||
$auditors = $db->query('SELECT no, name, officer_level, penalty, permission FROM general WHERE permission = \'auditor\' AND nation = %i', $nationID);
|
||||
@@ -112,8 +111,8 @@ $level = Util::convertArrayToDict(
|
||||
);
|
||||
|
||||
|
||||
$tigers = $db->query('SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
$tigers = $db->query('SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "killnum" AND value > 0 ORDER BY value DESC LIMIT 5',
|
||||
$nationID
|
||||
);// 오호장군
|
||||
@@ -122,9 +121,9 @@ $tigerstr = join(', ', array_map(function($arr){
|
||||
return "{$arr['name']}【{$number}】";
|
||||
}, $tigers));
|
||||
|
||||
$eagles = $db->query('SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "firenum" AND value > 0 ORDER BY value DESC LIMIT 7',
|
||||
$eagles = $db->query('SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "firenum" AND value > 0 ORDER BY value DESC LIMIT 7',
|
||||
$nationID
|
||||
);// 건안칠자
|
||||
$eaglestr = join(', ', array_map(function($arr){
|
||||
@@ -146,10 +145,10 @@ for($i=12; $i >= $lv; $i-=2) {
|
||||
$imageTemp2 = GetImageURL($level[$i2]['imgsvr']??0);
|
||||
?>
|
||||
<tr>
|
||||
<td width=98 align=center id=bg1><font size=4><?=getOfficerLevelText($i1, $nation['level'])?></font></td>
|
||||
<td width=98 align=center class='bg1'><font size=4><?=getOfficerLevelText($i1, $nation['level'])?></font></td>
|
||||
<td width=64 class='generalIcon' height=64 style='background:no-repeat center url("<?=$imageTemp1?>/<?=$level[$i1]['picture']??'default.jpg'?>");background-size:64px;'></td>
|
||||
<td width=332><font size=4><?=$level[$i1]['name']??'-'?>(<?=$level[$i1]['belong']??'-'?>년)</font></td>
|
||||
<td width=98 align=center id=bg1><font size=4><?=getOfficerLevelText($i2, $nation['level'])?></font></td>
|
||||
<td width=98 align=center class='bg1'><font size=4><?=getOfficerLevelText($i2, $nation['level'])?></font></td>
|
||||
<td width=64 class='generalIcon' height=64 style='background:no-repeat center url("<?=$imageTemp2?>/<?=$level[$i2]['picture']??'default.jpg'?>");background-size:64px;'></td>
|
||||
<td width=332><font size=4><?=$level[$i2]['name']??'-'?>(<?=$level[$i2]['belong']??'-'?>년)</font></td>
|
||||
</tr>
|
||||
@@ -158,11 +157,11 @@ for($i=12; $i >= $lv; $i-=2) {
|
||||
|
||||
?>
|
||||
<tr>
|
||||
<td width=98 align=center id=bg1>오호장군【승전】</td>
|
||||
<td width=98 align=center class='bg1'>오호장군【승전】</td>
|
||||
<td colspan=5><?=$tigerstr?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=98 align=center id=bg1>건안칠자【계략】</td>
|
||||
<td width=98 align=center class='bg1'>건안칠자【계략】</td>
|
||||
<td colspan=5><?=$eaglestr?></td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -170,7 +169,7 @@ for($i=12; $i >= $lv; $i-=2) {
|
||||
<tr><td colspan=6 height=5></td></tr>
|
||||
<tr><td colspan=2 align=center bgcolor=red>추 방</td></tr>
|
||||
<tr>
|
||||
<td width=498 align=right id=bg1>대상 장수</td>
|
||||
<td width=498 align=right class='bg1'>대상 장수</td>
|
||||
<td width=498>
|
||||
<?php
|
||||
|
||||
@@ -212,9 +211,9 @@ echo "
|
||||
<tr><td colspan=4 height=5></td></tr>
|
||||
<tr><td colspan=4 align=center bgcolor=blue>수 뇌 부 임 명</td></tr>
|
||||
<tr>
|
||||
<td width=98 align=right id=bg1>".getOfficerLevelText(12, $nation['level'])."</td>
|
||||
<td width=98 align=right class='bg1'>".getOfficerLevelText(12, $nation['level'])."</td>
|
||||
<td width=398>{$level[12]['name']} 【".CityConst::byID($level[12]['city'])->name."】</td>
|
||||
<td width=98 align=right id=bg1>{$officerLevelText}</td>
|
||||
<td width=98 align=right class='bg1'>{$officerLevelText}</td>
|
||||
<td width=398>
|
||||
";
|
||||
|
||||
@@ -240,7 +239,7 @@ if($meLevel >= 5 && !isOfficerSet($nation['chief_set'], 11)) {
|
||||
if(key_exists(11, $level)){
|
||||
echo "{$level[11]['name']} 【".CityConst::byID($level[11]['city'])->name."】";
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
echo "
|
||||
</td>
|
||||
@@ -251,11 +250,11 @@ for($i=10; $i >= $lv; $i--) {
|
||||
if($i % 2 == 0) { echo "<tr>"; }
|
||||
$officerLevelText = getOfficerLevelText($i, $nation['level']);
|
||||
echo "
|
||||
<td width=98 align=right id=bg1>{$officerLevelText}</td>
|
||||
<td width=98 align=right class='bg1'>{$officerLevelText}</td>
|
||||
<td width=398>
|
||||
";
|
||||
|
||||
|
||||
|
||||
if($meLevel >= 5 && !isOfficerSet($nation['chief_set'], $i)) {
|
||||
echo "
|
||||
<select id='genlist_{$i}' size=1 style=color:white;background-color:black;>
|
||||
@@ -295,13 +294,13 @@ if($meLevel == 12):
|
||||
<tr><td colspan='4' height='5'></td></tr>
|
||||
<tr><td colspan='4' align='center' bgcolor='purple'>외 교 권 자 임 명</td></tr>
|
||||
<tr>
|
||||
<td width=98 align=right id=bg1>외교권자</td>
|
||||
<td width=98 align=right class='bg1'>외교권자</td>
|
||||
<td width=398>
|
||||
<select id="selectAmbassador" multiple="multiple">
|
||||
</select>
|
||||
<button id='changeAmbassador' type='button'>임명</button>
|
||||
</td>
|
||||
<td width=98 align=right id=bg1>조언자</td>
|
||||
<td width=98 align=right class='bg1'>조언자</td>
|
||||
<td width=398>
|
||||
<select id="selectAuditor" multiple="multiple">
|
||||
</select>
|
||||
@@ -320,7 +319,7 @@ if($meLevel >= 5) {
|
||||
echo "
|
||||
<tr><td colspan=5 align=center bgcolor=orange>도 시 관 직 임 명</td></tr>
|
||||
<tr>
|
||||
<td colspan=3 align=right id=bg2>{$officerLevelText} 임명</td>
|
||||
<td colspan=3 align=right class='bg2'>{$officerLevelText} 임명</td>
|
||||
<td colspan=2>
|
||||
<select id='citylist_4' size=1 style=color:white;background-color:black;>
|
||||
";
|
||||
@@ -367,7 +366,7 @@ if($meLevel >= 5) {
|
||||
</tr>";
|
||||
$officerLevelText = getOfficerLevelText(3, $nation['level']);
|
||||
echo "<tr>
|
||||
<td colspan=3 align=right id=bg2>{$officerLevelText} 임명</td>
|
||||
<td colspan=3 align=right class='bg2'>{$officerLevelText} 임명</td>
|
||||
<td colspan=2>
|
||||
<select id='citylist_3' size=1 style=color:white;background-color:black;>
|
||||
";
|
||||
@@ -413,7 +412,7 @@ if($meLevel >= 5) {
|
||||
</tr>";
|
||||
$officerLevelText = getOfficerLevelText(2, $nation['level']);
|
||||
echo "<tr>
|
||||
<td colspan=3 align=right id=bg2>{$officerLevelText} 임명</td>
|
||||
<td colspan=3 align=right class='bg2'>{$officerLevelText} 임명</td>
|
||||
<td colspan=2>
|
||||
<select id='citylist_2' size=1 style=color:white;background-color:black;>
|
||||
";
|
||||
@@ -462,10 +461,10 @@ if($meLevel >= 5) {
|
||||
}
|
||||
echo "
|
||||
<tr>
|
||||
<td width=158 align=center id=bg1 colspan=2><font size=4>도 시</font></td>
|
||||
<td width=278 align=center id=bg1><font size=4>태 수 (사관) 【현재도시】</font></td>
|
||||
<td width=278 align=center id=bg1><font size=4>군 사 (사관) 【현재도시】</font></td>
|
||||
<td width=278 align=center id=bg1><font size=4>종 사 (사관) 【현재도시】</font></td>
|
||||
<td width=158 align=center class='bg1' colspan=2><font size=4>도 시</font></td>
|
||||
<td width=278 align=center class='bg1'><font size=4>태 수 (사관) 【현재도시】</font></td>
|
||||
<td width=278 align=center class='bg1'><font size=4>군 사 (사관) 【현재도시】</font></td>
|
||||
<td width=278 align=center class='bg1'><font size=4>종 사 (사관) 【현재도시】</font></td>
|
||||
</tr>
|
||||
";
|
||||
|
||||
@@ -495,15 +494,15 @@ foreach($db->query('SELECT city,name,level,region,officer_set from city where na
|
||||
$cityOfficerList = $officerList[$cityID]??[];
|
||||
?>
|
||||
<?php if($region != $city['region']): ?>
|
||||
<tr><td colspan=5 height=3 id=bg1></td></tr>
|
||||
<tr><td colspan=5 id=bg1><font size=4 color=skyblue> 【 <?=CityConst::$regionMap[$city['region']]?> 】 </font></td></tr>
|
||||
<tr><td colspan=5 height=3 class='bg1'></td></tr>
|
||||
<tr><td colspan=5 class='bg1'><font size=4 color=skyblue> 【 <?=CityConst::$regionMap[$city['region']]?> 】 </font></td></tr>
|
||||
<?php endif; $region = $city['region']; ?>
|
||||
<tr>
|
||||
<td width=78 align=center style='color:<?=$textColor?>;background-color:<?=$nationColor?>;font-size:1.2em;'>【<?=$citylevel[$city['level']]?>】</td>
|
||||
<td width=78 align=right style='color:<?=$textColor?>;background-color:<?=$nationColor?>;font-size:1.2em;'><?=$city['name']?> </td>
|
||||
|
||||
<?php foreach(Util::range(4, 1, -1) as $officerLevel): ?>
|
||||
<?php if(key_exists($officerLevel, $cityOfficerList)):
|
||||
<?php if(key_exists($officerLevel, $cityOfficerList)):
|
||||
$officer = $cityOfficerList[$officerLevel];
|
||||
?>
|
||||
<td style="color:<?=isOfficerSet($city['officer_set'], $officerLevel)?'orange':'white'?>;"><?=$officer['name']?>(<?=$officer['belong']?>년) 【<?=CityConst::byID($officer['city'])->name?>】</td>
|
||||
|
||||
+18
-22
@@ -37,13 +37,10 @@ $sel = [$type => "selected"];
|
||||
<title><?=UniqueConst::$serverName?>: 세력도시</title>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/jquery-ui.min.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-ui.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/ext.expand_city.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/extExpandCity.js')?>
|
||||
|
||||
</head>
|
||||
|
||||
@@ -129,10 +126,10 @@ foreach($cityList as $city){
|
||||
];
|
||||
|
||||
$cityOfficerList = $officerList[$cityID]??[];
|
||||
foreach($cityOfficerList as $cityOfficer){
|
||||
foreach($cityOfficerList as $cityOfficer){
|
||||
$officerName[$cityOfficer['officer_level']] = getColoredName($cityOfficer['name'], $cityOfficer['npc']);
|
||||
}
|
||||
|
||||
|
||||
if ($type == 10 && $city['region'] != $region) {
|
||||
echo "<br>";
|
||||
$region = $city['region'];
|
||||
@@ -151,41 +148,41 @@ foreach($cityList as $city){
|
||||
<td colspan=12 style=color:".newColor($nation['color'])."; bgcolor={$nation['color']}><font size=2>【 ".CityConst::$regionMap[$city['region']]." | ".CityConst::$levelMap[$city['level']]." 】 {$city['name']}</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center width=46 id=bg1>주민</td>
|
||||
<td align=center width=46 class='bg1'>주민</td>
|
||||
<td align=center width=140>{$city['pop']}/{$city['pop_max']}</td>
|
||||
<td align=center width=46 id=bg1>농업</td>
|
||||
<td align=center width=46 class='bg1'>농업</td>
|
||||
<td align=center width=140>{$city['agri']}/{$city['agri_max']}</td>
|
||||
<td align=center width=46 id=bg1>상업</td>
|
||||
<td align=center width=46 class='bg1'>상업</td>
|
||||
<td align=center width=140>{$city['comm']}/{$city['comm_max']}</td>
|
||||
<td align=center width=46 id=bg1>치안</td>
|
||||
<td align=center width=46 class='bg1'>치안</td>
|
||||
<td align=center width=140>{$city['secu']}/{$city['secu_max']}</td>
|
||||
<td align=center width=46 id=bg1>수비</td>
|
||||
<td align=center width=46 class='bg1'>수비</td>
|
||||
<td align=center width=140>{$city['def']}/{$city['def_max']}</td>
|
||||
<td align=center width=46 id=bg1>성벽</td>
|
||||
<td align=center width=46 class='bg1'>성벽</td>
|
||||
<td align=center width=140>{$city['wall']}/{$city['wall_max']}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>민심</td>
|
||||
<td align=center class='bg1'>민심</td>
|
||||
<td align=center>".round($city['trust'], 1)."</td>
|
||||
<td align=center id=bg1>시세</td>
|
||||
<td align=center class='bg1'>시세</td>
|
||||
<td align=center>{$city['trade']}%</td>
|
||||
<td align=center id=bg1>인구</td>
|
||||
<td align=center class='bg1'>인구</td>
|
||||
<td align=center>".round($city['pop']/$city['pop_max']*100, 2)." %</td>
|
||||
<td align=center id=bg1>태수</td>
|
||||
<td align=center class='bg1'>태수</td>
|
||||
<td align=center>";
|
||||
echo $officerName[4];
|
||||
echo "</td>
|
||||
<td align=center id=bg1>군사</td>
|
||||
<td align=center class='bg1'>군사</td>
|
||||
<td align=center>";
|
||||
echo $officerName[3];
|
||||
echo "</td>
|
||||
<td align=center id=bg1>종사</td>
|
||||
<td align=center class='bg1'>종사</td>
|
||||
<td align=center>";
|
||||
echo $officerName[2];
|
||||
echo "</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>장수</td>
|
||||
<td align=center class='bg1'>장수</td>
|
||||
<td colspan=11>";
|
||||
$generalList = $db->query('SELECT npc, name FROM general WHERE city = %i AND nation = %i', $city['city'], $me['nation']);
|
||||
if (!$generalList) {
|
||||
@@ -209,4 +206,3 @@ foreach($cityList as $city){
|
||||
</body>
|
||||
<div id="helper_genlist" style="display:none;"></div>
|
||||
</html>
|
||||
|
||||
|
||||
+18
-19
@@ -47,9 +47,9 @@ if($gameStor->isunited){
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
|
||||
</head>
|
||||
|
||||
@@ -104,21 +104,21 @@ $generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special
|
||||
echo"
|
||||
<table align=center class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=64 align=center id=bg1>얼 굴</td>
|
||||
<td width=98 align=center id=bg1>이 름</td>
|
||||
<td width=78 align=center id=bg1>관 직</td>
|
||||
<td width=68 align=center id=bg1>계 급</td>
|
||||
<td width=68 align=center id=bg1>명 성</td>
|
||||
<td width=68 align=center id=bg1>봉 록</td>
|
||||
<td width=48 align=center id=bg1>통솔</td>
|
||||
<td width=48 align=center id=bg1>무력</td>
|
||||
<td width=48 align=center id=bg1>지력</td>
|
||||
<td width=68 align=center id=bg1>자 금</td>
|
||||
<td width=68 align=center id=bg1>군 량</td>
|
||||
<td width=48 align=center id=bg1>성 격</td>
|
||||
<td width=78 align=center id=bg1>특 기</td>
|
||||
<td width=48 align=center id=bg1>사 관</td>
|
||||
<td width=70 align=center id=bg1>벌점</td>
|
||||
<td width=64 align=center class='bg1'>얼 굴</td>
|
||||
<td width=98 align=center class='bg1'>이 름</td>
|
||||
<td width=78 align=center class='bg1'>관 직</td>
|
||||
<td width=68 align=center class='bg1'>계 급</td>
|
||||
<td width=68 align=center class='bg1'>명 성</td>
|
||||
<td width=68 align=center class='bg1'>봉 록</td>
|
||||
<td width=48 align=center class='bg1'>통솔</td>
|
||||
<td width=48 align=center class='bg1'>무력</td>
|
||||
<td width=48 align=center class='bg1'>지력</td>
|
||||
<td width=68 align=center class='bg1'>자 금</td>
|
||||
<td width=68 align=center class='bg1'>군 량</td>
|
||||
<td width=48 align=center class='bg1'>성 격</td>
|
||||
<td width=78 align=center class='bg1'>특 기</td>
|
||||
<td width=48 align=center class='bg1'>사 관</td>
|
||||
<td width=70 align=center class='bg1'>벌점</td>
|
||||
</tr>";
|
||||
foreach($generalList as $general){
|
||||
|
||||
@@ -183,4 +183,3 @@ foreach($generalList as $general){
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
+23
-24
@@ -27,9 +27,9 @@ if($nationID == 0) {
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 세력정보</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
@@ -96,57 +96,57 @@ if ($budgetricediff > 0) {
|
||||
<td colspan=8 align=center style='color:<?=newColor($nation['color'])?>;background-color:<?=$nation['color']?>'>【<?=$nation['name']?>】</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=98 align=center id=bg1>총주민</td>
|
||||
<td width=98 align=center class='bg1'>총주민</td>
|
||||
<td width=198 align=center><?=number_format($currPop)?>/<?=number_format($maxPop)?></td>
|
||||
<td width=98 align=center id=bg1>총병사</td>
|
||||
<td width=98 align=center class='bg1'>총병사</td>
|
||||
<td width=198 align=center><?=number_format($currCrew)?>/<?=number_format($maxCrew)?></td>
|
||||
<td width=98 align=center id=bg1>국 력</td>
|
||||
<td width=98 align=center class='bg1'>국 력</td>
|
||||
<td width=298 align=center colspan=3><?=$nation['power']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>국 고</td>
|
||||
<td align=center class='bg1'>국 고</td>
|
||||
<td align=center><?=number_format($nation['gold'])?></td>
|
||||
<td align=center id=bg1>병 량</td>
|
||||
<td align=center class='bg1'>병 량</td>
|
||||
<td align=center><?=number_format($nation['rice'])?></td>
|
||||
<td align=center id=bg1>세 율</td>
|
||||
<td align=center class='bg1'>세 율</td>
|
||||
<td align=center colspan=3><?=$nation['rate']?> %</td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>세금/단기</td>
|
||||
<td align=center class='bg1'>세금/단기</td>
|
||||
<td align=center>+<?=number_format($goldIncome)?> / +<?=number_format($warIncome)?></td>
|
||||
<td align=center id=bg1>세곡/둔전</td>
|
||||
<td align=center class='bg1'>세곡/둔전</td>
|
||||
<td align=center>+<?=number_format($riceIncome)?> / +<?=number_format($wallIncome)?></td>
|
||||
<td align=center id=bg1>지급률</td>
|
||||
<td align=center class='bg1'>지급률</td>
|
||||
<td align=center colspan=3><?=$nation['bill']?> %</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>수입/지출</td>
|
||||
<td align=center class='bg1'>수입/지출</td>
|
||||
<td align=center>+<?=number_format($totalGoldIncome)?> / -<?=number_format($outcome)?></td>
|
||||
<td align=center id=bg1>수입/지출</td>
|
||||
<td align=center class='bg1'>수입/지출</td>
|
||||
<td align=center>+<?=number_format($totalRiceIncome)?> / -<?=number_format($outcome)?></td>
|
||||
<td align=center id=bg1>속 령</td>
|
||||
<td align=center class='bg1'>속 령</td>
|
||||
<td width=98 align=center><?=count($cityList)?></td>
|
||||
<td width=98 align=center id=bg1>장 수</td>
|
||||
<td width=98 align=center class='bg1'>장 수</td>
|
||||
<td width=98 align=center><?=$nation['gennum']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1>국고 예산</td>
|
||||
<td align=center class='bg1'>국고 예산</td>
|
||||
<td align=center><?=number_format($budgetgold)?> (<?=$budgetgolddiff?>)</td>
|
||||
<td align=center id=bg1>병량 예산</td>
|
||||
<td align=center class='bg1'>병량 예산</td>
|
||||
<td align=center><?=number_format($budgetrice)?> (<?=$budgetricediff?>)</td>
|
||||
<td align=center id=bg1>기술력</td>
|
||||
<td align=center class='bg1'>기술력</td>
|
||||
<td align=center><?=number_format(floor($nation['tech']))?></td>
|
||||
<td align=center id=bg1>작 위</td>
|
||||
<td align=center class='bg1'>작 위</td>
|
||||
<td align=center><?=getNationLevel($nation['level'])?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center valign=top id=bg1> 속령일람 :</td>
|
||||
<td align=center valign=top class='bg1'> 속령일람 :</td>
|
||||
<td colspan=7><?=join(', ', $cityNames)?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center valign=top id=bg1>국가열전</td>
|
||||
<td colspan=7 id=bg0><?=formatHistoryToHTML(getNationHistoryLogAll($nation['nation']))?></td>
|
||||
<td align=center valign=top class='bg1'>국가열전</td>
|
||||
<td colspan=7 class='bg0'><?=formatHistoryToHTML(getNationHistoryLogAll($nation['nation']))?></td>
|
||||
</tr>
|
||||
</table>
|
||||
<br>
|
||||
@@ -158,4 +158,3 @@ if ($budgetricediff > 0) {
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
+164
-154
@@ -1,154 +1,164 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$showDieImmediatelyBtn = false;
|
||||
$availableDieImmediately = false;
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
increaseRefresh("내정보", 1);
|
||||
|
||||
$me = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
$myset = $me->getVar('myset');
|
||||
if ($myset > 0) {
|
||||
$submit = 'button';
|
||||
} else {
|
||||
$submit = 'hidden';
|
||||
}
|
||||
|
||||
$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2);
|
||||
if($gameStor->turntime <= $gameStor->opentime){
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
if($me->getNPCType() == 0){
|
||||
$showDieImmediatelyBtn = true;
|
||||
if($targetTime <= TimeUtil::now()){
|
||||
$availableDieImmediately = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$use_treatment = $me->getAuxVar('use_treatment')??10;
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 내정보</title>
|
||||
<script>
|
||||
var availableDieImmediately = <?=$availableDieImmediately?'true':'false'?>;
|
||||
</script>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/myPage.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td>내 정 보<br><?=backButton()?></td></tr>
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=50%>
|
||||
<?php generalInfo($me); ?>
|
||||
<?php generalInfo2($me); ?>
|
||||
</td>
|
||||
<td width=50% valign=top style="padding-left:4ch;">
|
||||
토너먼트 【
|
||||
<input type=radio class='tnmt' name=tnmt value=0 <?=$me->getVar('tnmt')==0?"checked":""; ?>>수동참여
|
||||
<input type=radio class='tnmt' name=tnmt value=1 <?=$me->getVar('tnmt')==1?"checked":""; ?>>자동참여
|
||||
】<br>
|
||||
∞<span style='color:orange'>개막직전 남는자리가 있을경우 랜덤하게 참여합니다.</span><br><br>
|
||||
|
||||
환약 사용 【<select id='use_treatment' name='use_treatment'>
|
||||
<option value=10 <?=$use_treatment==10?"selected":""; ?>>경상</option>
|
||||
<option value=20 <?=$use_treatment==21?"selected":""; ?>>중상</option>
|
||||
<option value=40 <?=$use_treatment==41?"selected":""; ?>>심각</option>
|
||||
<option value=60 <?=$use_treatment==61?"selected":""; ?>>위독</option>
|
||||
<option value=100 <?=$use_treatment==100?"selected":""; ?>>사용안함</option>
|
||||
</select>】<br>
|
||||
∞<span style='color:orange'>부상을 입었을 때 환약을 사용하는 기준입니다.</span><br><br>
|
||||
|
||||
수비 【<select id='defence_train' name='defence_train'>
|
||||
<option value=90 <?=$me->getVar('defence_train')==90?"selected":""; ?>>☆(훈사90)</option>
|
||||
<option value=80 <?=$me->getVar('defence_train')==80?"selected":""; ?>>◎(훈사80)</option>
|
||||
<option value=60 <?=$me->getVar('defence_train')==60?"selected":""; ?>>○(훈사60)</option>
|
||||
<option value=40 <?=$me->getVar('defence_train')==40?"selected":""; ?>>△(훈사40)</option>
|
||||
<option value=999 <?=$me->getVar('defence_train')==999?"selected":""; ?>>×[훈련, 사기 -3]</option>
|
||||
</select>
|
||||
】<br><br>
|
||||
<input type=<?=$submit?> id='set_my_setting' name=btn style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px; value=설정저장><br>
|
||||
∞<span style='color:orange'>설정저장은 이달중 <?=$myset?>회 남았습니다.</span><br><br>
|
||||
<?php if(!($gameStor->autorun_user['limit_minutes']??false)): ?>
|
||||
휴 가 신 청<br>
|
||||
<button type="button" id='vacation' style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>휴가 신청</button><br><br>
|
||||
<?php endif; ?>
|
||||
<!--빙의 해제용 삭턴 조절<br>
|
||||
<a href="b_myPage.php?detachNPC=1"><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>빙의 해체 요청</button></a>-->
|
||||
|
||||
<?php if($showDieImmediatelyBtn): ?>
|
||||
가오픈 기간 내 장수 삭제 (<?=substr($targetTime, 0, 19)?> 부터)<br>
|
||||
<a href="c_die_immediately.php" id='die_immediately'><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>장수 삭제</button></a><br><br>
|
||||
<?php endif; ?>
|
||||
|
||||
개인용 CSS<br>
|
||||
<textarea id='custom_css' style='color:white;background-color:black;width:420px;height:150px;'></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1><font color=skyblue size=3>개인 기록</font></td>
|
||||
<td align=center id=bg1><font color=orange size=3>전투 기록</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
<div id='generalActionPlate'>
|
||||
<?=formatHistoryToHTML(getGeneralActionLogRecent($generalID, 24), 'generalAction')?>
|
||||
</div>
|
||||
<button type="button" class="load_old_log btn btn-secondary btn-block" data-log_type="generalAction">이전 로그 불러오기</button>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<div id='battleDetailPlate'>
|
||||
<?=formatHistoryToHTML(getBattleDetailLogRecent($generalID, 24), 'battleDetail')?>
|
||||
</div>
|
||||
<button type="button" class="load_old_log btn btn-secondary btn-block" data-log_type="battleDetail">이전 로그 불러오기</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center id=bg1><font color=skyblue size=3>장수 열전</font></td>
|
||||
<td align=center id=bg1><font color=orange size=3>전투 결과</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
<?=formatHistoryToHTML(getGeneralHistoryLogAll($generalID))?>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<div id='battleResultPlate'>
|
||||
<?=formatHistoryToHTML(getBattleResultRecent($generalID, 24), 'battleResult')?>
|
||||
</div>
|
||||
<button type="button" class="load_old_log btn btn-secondary btn-block" data-log_type="battleResult">이전 로그 불러오기</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td><?=backButton()?></td></tr>
|
||||
<tr><td><?=banner()?></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$showDieImmediatelyBtn = false;
|
||||
$availableDieImmediately = false;
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
|
||||
|
||||
increaseRefresh("내정보", 1);
|
||||
|
||||
$me = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
$myset = $me->getVar('myset');
|
||||
if ($myset > 0) {
|
||||
$submit = 'button';
|
||||
} else {
|
||||
$submit = 'hidden';
|
||||
}
|
||||
|
||||
$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2);
|
||||
if($gameStor->turntime <= $gameStor->opentime){
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
if($me->getNPCType() == 0){
|
||||
$showDieImmediatelyBtn = true;
|
||||
if($targetTime <= TimeUtil::now()){
|
||||
$availableDieImmediately = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$use_treatment = $me->getAuxVar('use_treatment')??10;
|
||||
$use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn')??1;
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 내정보</title>
|
||||
<script>
|
||||
var availableDieImmediately = <?=$availableDieImmediately?'true':'false'?>;
|
||||
</script>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printJS('dist_js/myPage.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td>내 정 보<br><?=backButton()?></td></tr>
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=50%>
|
||||
<?php generalInfo($me); ?>
|
||||
<?php generalInfo2($me); ?>
|
||||
</td>
|
||||
<td width=50% valign=top style="padding-left:4ch;">
|
||||
토너먼트 【
|
||||
<input type=radio class='tnmt' name=tnmt value=0 <?=$me->getVar('tnmt')==0?"checked":""; ?>>수동참여
|
||||
<input type=radio class='tnmt' name=tnmt value=1 <?=$me->getVar('tnmt')==1?"checked":""; ?>>자동참여
|
||||
】<br>
|
||||
∞<span style='color:orange'>개막직전 남는자리가 있을경우 랜덤하게 참여합니다.</span><br><br>
|
||||
|
||||
환약 사용 【<select id='use_treatment' name='use_treatment'>
|
||||
<option value=10 <?=($use_treatment==10)?"selected":""; ?>>경상</option>
|
||||
<option value=21 <?=($use_treatment==21)?"selected":""; ?>>중상</option>
|
||||
<option value=41 <?=($use_treatment==41)?"selected":""; ?>>심각</option>
|
||||
<option value=61 <?=($use_treatment==61)?"selected":""; ?>>위독</option>
|
||||
<option value=100 <?=($use_treatment==100)?"selected":""; ?>>사용안함</option>
|
||||
</select>】<br>
|
||||
∞<span style='color:orange'>부상을 입었을 때 환약을 사용하는 기준입니다.</span><br><br>
|
||||
<?php if(($gameStor->autorun_user['options']['chief'])??false) : ?>
|
||||
자동 사령턴 허용 【<select id='use_auto_nation_turn' name='use_auto_nation_turn'>
|
||||
<option value=1 <?=$use_auto_nation_turn?"selected":""; ?>>허용</option>
|
||||
<option value=0 <?=(!$use_auto_nation_turn)?"selected":""; ?>>허용 안함</option>
|
||||
</select>】<br>
|
||||
∞<span style='color:orange'>수뇌가 되었을 때 휴식 턴이어도 적당한 턴을 알아서 넣는 것을 허용합니다.</span><br><br>
|
||||
<?php endif; ?>
|
||||
수비 【<select id='defence_train' name='defence_train'>
|
||||
<?php foreach([90, 80, 60, 40] as $targetDefenceTrain): ?>
|
||||
<option value='<?=$targetDefenceTrain?>' <?=$me->getVar('defence_train')==$targetDefenceTrain?"selected":""; ?>><?=formatDefenceTrain($targetDefenceTrain)?>(훈사<?=$targetDefenceTrain?>)</option>
|
||||
<?php endforeach; ?>
|
||||
<option value=999 <?=$me->getVar('defence_train')==999?"selected":""; ?>><?=formatDefenceTrain(999)?>[훈련, 사기 -3]</option>
|
||||
</select>
|
||||
】<br><br>
|
||||
<input type=<?=$submit?> id='set_my_setting' name=btn style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px; value=설정저장><br>
|
||||
∞<span style='color:orange'>설정저장은 이달중 <?=$myset?>회 남았습니다.</span><br><br>
|
||||
<?php if(!($gameStor->autorun_user['limit_minutes']??false)): ?>
|
||||
휴 가 신 청<br>
|
||||
<button type="button" id='vacation' style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>휴가 신청</button><br><br>
|
||||
<?php endif; ?>
|
||||
<!--빙의 해제용 삭턴 조절<br>
|
||||
<a href="b_myPage.php?detachNPC=1"><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>빙의 해체 요청</button></a>-->
|
||||
|
||||
<?php if($showDieImmediatelyBtn): ?>
|
||||
가오픈 기간 내 장수 삭제 (<?=substr($targetTime, 0, 19)?> 부터)<br>
|
||||
<a href="c_die_immediately.php" id='die_immediately'><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>장수 삭제</button></a><br><br>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if($gameStor->npcmode==2 && $me->getNPCType()==0): ?>
|
||||
다른 장수 선택 (<?=substr($me->getAuxVar('next_change')??TimeUtil::now(), 0, 19)?> 부터)<br>
|
||||
<a href="select_general_from_pool.php" id='select_general_from_pool'><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>다른 장수 선택</button></a><br><br>
|
||||
<?php endif; ?>
|
||||
|
||||
개인용 CSS<br>
|
||||
<textarea id='custom_css' style='color:white;background-color:black;width:420px;height:150px;'></textarea>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center class='bg1'><font color=skyblue size=3>개인 기록</font></td>
|
||||
<td align=center class='bg1'><font color=orange size=3>전투 기록</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
<div id='generalActionPlate'>
|
||||
<?=formatHistoryToHTML(getGeneralActionLogRecent($generalID, 24), 'generalAction')?>
|
||||
</div>
|
||||
<button type="button" class="load_old_log btn btn-secondary btn-block" data-log_type="generalAction">이전 로그 불러오기</button>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<div id='battleDetailPlate'>
|
||||
<?=formatHistoryToHTML(getBattleDetailLogRecent($generalID, 24), 'battleDetail')?>
|
||||
</div>
|
||||
<button type="button" class="load_old_log btn btn-secondary btn-block" data-log_type="battleDetail">이전 로그 불러오기</button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td align=center class='bg1'><font color=skyblue size=3>장수 열전</font></td>
|
||||
<td align=center class='bg1'><font color=orange size=3>전투 결과</font></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign=top>
|
||||
<?=formatHistoryToHTML(getGeneralHistoryLogAll($generalID))?>
|
||||
</td>
|
||||
<td valign=top>
|
||||
<div id='battleResultPlate'>
|
||||
<?=formatHistoryToHTML(getBattleResultRecent($generalID, 24), 'battleResult')?>
|
||||
</div>
|
||||
<button type="button" class="load_old_log btn btn-secondary btn-block" data-log_type="battleResult">이전 로그 불러오기</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<table align=center width=1000 class='tb_layout bg0'>
|
||||
<tr><td><?=backButton()?></td></tr>
|
||||
<tr><td><?=banner()?></td></tr>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -1,420 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['autorun_user', 'develcost']);
|
||||
|
||||
increaseRefresh("NPC 정책", 1);
|
||||
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no, npc, nation, city, officer_level, con, turntime, belong, permission, penalty FROM general WHERE owner=%i', $userID);
|
||||
|
||||
$nationID = $me['nation'];
|
||||
$nation = $db->queryFirstRow('SELECT nation,level,name,color,type,gold,rice,bill,tech,rate,scout,war,secretlimit,capital FROM nation WHERE nation = %i', $nationID);
|
||||
|
||||
$con = checkLimit($me['con']);
|
||||
if ($con >= 2) {
|
||||
printLimitMsg($me['turntime']);
|
||||
exit();
|
||||
}
|
||||
|
||||
$permission = checkSecretPermission($me);
|
||||
if ($permission < 0) {
|
||||
echo '국가에 소속되어있지 않습니다.';
|
||||
die();
|
||||
} else if ($permission < 1) {
|
||||
echo "권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.";
|
||||
die();
|
||||
}
|
||||
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationStor->cacheValues(['npc_nation_policy', 'npc_general_policy']);
|
||||
$gameStor->cacheAll();
|
||||
|
||||
$general = new General($me, null, null, $nation, $gameStor->year, $gameStor->month, false);
|
||||
|
||||
$rawServerPolicy = $gameStor->getValue('npc_nation_policy') ?? [];
|
||||
$rawNationPolicy = $nationStor->getValue('npc_nation_policy') ?? [];
|
||||
$rawServerGeneralPolicy = $gameStor->getValue('npc_general_policy') ?? [];
|
||||
$rawNationGeneralPolicy = $nationStor->getValue('npc_general_policy') ?? [];
|
||||
|
||||
$defaultNationPolicy = ($rawServerPolicy['values'] ?? []) + AutorunNationPolicy::$defaultPolicy;
|
||||
$currentNationPolicy = ($rawNationPolicy['values'] ?? []) + $defaultNationPolicy;
|
||||
|
||||
$defaultNationPriority = $rawServerPolicy['priority'] ?? (AutorunNationPolicy::$defaultPriority);
|
||||
$currentNationPriority = $rawNationPolicy['priority'] ?? $defaultNationPriority;
|
||||
|
||||
$defaultGeneralActionPriority = $rawServerGeneralPolicy['priority'] ?? (AutorunGeneralPolicy::$default_priority);
|
||||
$currentGeneralActionPriority = $rawNationGeneralPolicy['priority'] ?? $defaultGeneralActionPriority;
|
||||
|
||||
$autoPolicyVariable = [];
|
||||
if ($currentNationPolicy['reqHumanWarUrgentRice'] ?? 0) {
|
||||
$autoPolicyVariable['reqHumanWarUrgentRice'] = $currentNationPolicy['reqHumanWarUrgentRice'];
|
||||
}
|
||||
if ($currentNationPolicy['reqHumanWarUrgentGold'] ?? 0) {
|
||||
$autoPolicyVariable['reqHumanWarUrgentGold'] = $currentNationPolicy['reqHumanWarUrgentGold'];
|
||||
}
|
||||
$autoPolicy = new AutorunNationPolicy($general, ($gameStor->autorun_user)['options'], ['values' => $autoPolicyVariable], null, $nation, $gameStor->getAll(true));
|
||||
$zeroPolicy = new AutorunNationPolicy($general, ($gameStor->autorun_user)['options'], null, null, $nation, $gameStor->getAll(true));
|
||||
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?= UniqueConst::$serverName ?>: 임시 NPC 정책</title>
|
||||
<script>
|
||||
var nationID = <?= $nationID ?>;
|
||||
|
||||
var defaultNationPolicy = <?= Json::encode($defaultNationPolicy) ?>;
|
||||
var currentNationPolicy = <?= Json::encode($currentNationPolicy) ?>;
|
||||
|
||||
var defaultNationPriority = <?= Json::encode($defaultNationPriority) ?>;
|
||||
var currentNationPriority = <?= Json::encode($currentNationPriority) ?>;
|
||||
var availableNationPriorityItems = <?= Json::encode(AutorunNationPolicy::$defaultPriority) ?>;
|
||||
|
||||
var defaultGeneralActionPriority = <?= Json::encode($defaultGeneralActionPriority) ?>;
|
||||
var currentGeneralActionPriority = <?= Json::encode($currentGeneralActionPriority) ?>;
|
||||
var availableGeneralActionPriorityItems = <?= Json::encode(AutorunGeneralPolicy::$default_priority) ?>;
|
||||
|
||||
var btnHelpMessage = {
|
||||
'선전포고': '군주가 NPC이고, 전쟁중이 아닐 때,<br>주변국중 하나를 골라 선포합니다.<br><br>선포 시점은 다음을 참고합니다.<br>- 인구율<br>- 도시내정률<br>- NPC전투장권장 금 충족률<br>- NPC전투장권장 쌀 충족률<br><br>국력이 낮은 국가를 조금 더 선호합니다.',
|
||||
'천도': '인구가 많은 곳을 찾아 천도를 시도합니다.<br>영토의 가운데를 선호합니다.<br><br>도시 인구가 충분하다면, 굳이 천도하지는 않습니다.',
|
||||
'유저장긴급포상': '금/쌀이 부족한 유저전투장에게 긴급하게 포상합니다.<br>국고가 권장량보다 적어지더라도 시도합니다.',
|
||||
'부대전방발령': '(작동하지 않음)<br>전투 부대를 접경으로 발령합니다.<br>수도->시작점->도착점 경로를 따릅니다.',
|
||||
'유저장구출발령': '아군 영토에 있지 않은 유저장을 아군 영토로 발령합니다.<br>곧 집합하는 부대에 탑승한 경우는 제외합니다.',
|
||||
'유저장후방발령': '유저전투장 중에<br>- 병력이 충분하지 않고,<br>- 도시의 인구가 제자리 징병할 수 있을 정도로 충분하지 않고,<br>- 부대에 탑승하지 않았다면,<br>인구가 충분한 후방도시로 발령합니다.',
|
||||
'부대유저장후방발령': '접경에 위치한 부대에 탑승한 유저전투장 중에,<br>- 병력이 충분하지 않고,<br>- 첫 턴이 징병턴이며,<br>- 부대장 집합 턴 사이라면,<br>인구가 충분한 후방도시로 발령합니다.<br><br>부대장의 위치와 유저장의 위치가 다르다면 발령하지 않습니다.',
|
||||
'유저장전방발령': '후방에 있는 유저장이<br>- 병력을 가지고 있으며,<br>- 곧 훈련/사기진작이 완료될 것 같으면,<br>전방으로 발령합니다.<br><br>도시 관직이 많이 임명된 도시를 선호합니다.',
|
||||
'유저장포상': '금/쌀이 부족한 유저장에게 포상합니다.<br>유저전투장과 유저내정장은 각각 기준을 따릅니다.<br>국고 권장량을 가급적 지킵니다.',
|
||||
'부대후방발령': '(작동하지 않음)<br>후방 부대가 위치한 도시의 인구가 충분하지 않을 경우,<br>인구가 충분한 도시로 발령합니다.',
|
||||
'부대구출발령': '전투 부대, 후방 부대가 아닌 부대가 아군 영토에 있지 않을 때,<br>전방 도시 중 하나를 골라 발령합니다.',
|
||||
'NPC긴급포상': '금/쌀이 부족한 NPC전투장에게 긴급하게 포상합니다.<br>국고가 권장량보다 \'약간\' 적어지더라도 시도합니다.',
|
||||
'NPC구출발령': '아군 영토에 있지 않은 NPC장을 아군 영토로 발령합니다.',
|
||||
'NPC후방발령': 'NPC전투장 중에<br>- 병력이 충분하지 않고,<br>- 도시의 인구가 제자리 징병할 수 있을 정도로 충분하지 않고,<br>- 부대에 탑승하지 않았다면,<br>인구가 충분한 후방도시로 발령합니다.',
|
||||
'NPC포상': '금/쌀이 부족한 유저장에게 포상합니다.<br>NPC전투장과 NPC내정장은 각각 기준을 따릅니다.<br>국고 권장량을 가급적 지킵니다.',
|
||||
'NPC전방발령': '후방에 있는 유저장이<br>- 병력을 가지고 있으며,<br>- 곧 훈련/사기진작이 완료될 것 같으면,<br>전방으로 발령합니다.<br><br>도시 관직이 많이 임명된 도시를 선호합니다.',
|
||||
'유저장내정발령': '내정중인 유저장이 위치한 도시의 내정률이 95% 이상이면<br>개발되지 않은 도시로 발령합니다.',
|
||||
'NPC내정발령': '내정중인 NPC장이 위치한 도시의 내정률이 95% 이상이면<br>개발되지 않은 도시로 발령합니다.',
|
||||
'NPC몰수': '국고가 부족하다면 NPC에게서 몰수합니다. 내정NPC장은 국고가 부족하지 않아도 몰수합니다.',
|
||||
|
||||
'NPC사망대비': 'NPC의 사망까지 5턴 이내인 경우, 헌납합니다.<br>헌납할 금쌀이 없다면 물자조달을 수행합니다.',
|
||||
'귀환': '아국 도시에 있지 않다면 귀환합니다.',
|
||||
'금쌀구매': '전쟁 중에 금쌀의 비율이 크게 차이난다면 금쌀을 거래하여 비슷하게 맞춥니다.<br>금쌀 비율이 적절하는지 판단하는데 살상률을 포함합니다.<br>NPC는 상인이 없어도 금쌀을 구매할 수 있습니다.<br><br>또는 금쌀 한쪽이 지나치게 적은 경우에는 내정 중에도 금쌀을 거래합니다.',
|
||||
'출병': '충분한 병력과 충분한 훈련/사기를 가지고 있는 경우 출병합니다.<br>접경이 여럿인 경우 무작위로 선택합니다.<br><br>타국과 전쟁중인 경우 공백지로는 출병하지 않습니다.',
|
||||
'긴급내정': '전쟁중에 민심이 70 미만이거나,<br>인구가 제자리 징병이 가능하지 않을 정도로 적을 경우,<br>일정확률로 주민선정과 정착장려를 수행합니다.<br><br>통솔이 높을 수록 수행할 확률이 높습니다.',
|
||||
'전투준비': '충분한 병력을 가지고 있지만 훈련과 사기가 부족한 경우 훈련과 사기진작을 수행합니다.',
|
||||
'전방워프': '전투장이 충분한 병력을 가지고 있다면 전방으로 이동합니다.',
|
||||
'NPC헌납': '국고가 부족한데 NPC전쟁장이 충분한 금쌀(권장량 대비 1.5배)을 가지고 있다면 일부를 헌납합니다. <br>NPC내정장은 국고가 넉넉하더라도 충분한 금쌀을 가지고 있다면 권장량만 유지하고 헌납합니다.',
|
||||
'징병': '전쟁 중 병력을 소진하였다면 재 징병합니다.<br><br>기존에 사용한 병종군 중에서 사용가능한 병종을 랜덤하게 선택합니다.<br>고급 병종을 선택할 확률이 조금 더 높습니다.<br><br>NPC의 경우 도시의 인구가 충분하지 않다면 징병을 할 확률이 감소합니다.<br><br>유저장은 최대한 고급병종을 유지하며,<br>유저장 모병이 허용되는 경우 모병을 3회할 수 있다면 모병합니다.',
|
||||
'후방워프': '전쟁 중 병력을 소진하였는데 도시의 인구가 충분하지 않다면,<br>인구가 많은 도시로 이동합니다.',
|
||||
'전쟁내정': '전쟁 중 수행하는 내정입니다.<br>정착장려, 기술연구의 확률이 좀 더 높고,<br>치안강화, 농지개간, 상업투자의 확률이 낮습니다.<br><br>내정이 가능하다 하더라도 전시임을 고려해,<br>30% 확률로 다른 턴을 수행합니다.',
|
||||
'소집해제': '전쟁 중이 아닌 데 병력이 남아있는 경우,<br>3/4 확률로 소집해제합니다.',
|
||||
'일반내정': '도시에서 내정을 수행합니다. 낮은 내정일 수록 수행할 확률이 높습니다.<br>기술 연구는 1등급 이상 뒤쳐지지 않도록 노력합니다.',
|
||||
'내정워프': '도시에서 더이상 내정을 수행할 수 없는 경우,<br>일정확률로 내정이 부족한 다른 도시로 이동합니다.',
|
||||
};
|
||||
</script>
|
||||
<?= WebUtil::printJS('../e_lib/jquery-3.3.1.min.js') ?>
|
||||
<?= WebUtil::printJS('../e_lib/Sortable.min.js') ?>
|
||||
<?= WebUtil::printJS('../e_lib/jquery-sortable.js') ?>
|
||||
<?= WebUtil::printJS('../e_lib/bootstrap.bundle.min.js') ?>
|
||||
<?= WebUtil::printJS('../e_lib/jquery_toast/toast.js') ?>
|
||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||
<?= WebUtil::printJS('js/common.js') ?>
|
||||
<?= WebUtil::printJS('js/npc_control.js') ?>
|
||||
|
||||
<?= WebUtil::printCSS('../e_lib/bootstrap.min.css') ?>
|
||||
<?= WebUtil::printCSS('../e_lib/font_awesome/css/all.min.css') ?>
|
||||
<?= WebUtil::printCSS('../e_lib/jquery_toast/toast.css') ?>
|
||||
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||
<?= WebUtil::printCSS('css/common.css') ?>
|
||||
<?= WebUtil::printCSS('css/npc_control.css') ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id='container' class='tb_layout bg0' style='width:1000px;margin:auto;border:solid 1px #888888;'>
|
||||
<div class='tb_layout bg0'>임시 NPC 정책<br>
|
||||
<?= backButton() ?></div>
|
||||
|
||||
<div class='bg1 section_bar'>국가 정책</div>
|
||||
<div class="text-right px-3"><small class="form-text text-muted">
|
||||
최근 설정: <?= $rawNationPolicy['valueSetter'] ?? '-없음-' ?> (<?= $rawNationPolicy['valueSetTime'] ?? '설정 기록 없음' ?>)
|
||||
</small></div>
|
||||
<div class="form_list">
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqNationGold" class="col-sm-6 col-form-label">국가 권장 금</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqNationGold" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">이보다 많으면 포상, 적으면 몰수/헌납합니다.(긴급포상 제외)</small></div>
|
||||
</div>
|
||||
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqNationRice" class="col-sm-6 col-form-label">국가 권장 쌀</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqNationRice" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">이보다 많으면 포상, 적으면 몰수/헌납합니다.(긴급포상 제외)</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqHumanWarUrgentGold" class="col-sm-6 col-form-label">유저전투장 긴급포상 금</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqHumanWarUrgentGold" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">
|
||||
유저장긴급포상시 이보다 금이 적은 장수에게 포상합니다.<br>
|
||||
0이면 보병 6회 징병(<?= number_format(GameConst::$defaultStatMax * 100) ?> * 6) 가능한 금을 기준으로 하며, 그 수치는 현재 <?= number_format($zeroPolicy->reqHumanWarUrgentGold) ?>입니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqHumanWarUrgentRice" class="col-sm-6 col-form-label">유저전투장 긴급포상 쌀</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqHumanWarUrgentRice" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">유저장긴급포상시 이보다 쌀이 적은 장수에게 포상합니다.<br>0이면 기본 병종으로 <?= number_format(GameConst::$defaultStatMax * 100 * 6) ?>명 사살 가능한 쌀을 기준으로 하며, 그 수치는 현재 <?= number_format($zeroPolicy->reqHumanWarUrgentRice) ?>입니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqHumanWarRecommandGold" class="col-sm-6 col-form-label">유저전투장 권장 금</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqHumanWarRecommandGold" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">유저전투장에게 주는 금입니다. 이보다 적으면 포상합니다. <br>
|
||||
0이면 유저전투장 긴급포상 금의 2배를 기준으로 하며, 그 수치는 현재 <?= number_format($autoPolicy->reqHumanWarRecommandGold) ?>입니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqHumanWarRecommandRice" class="col-sm-6 col-form-label">유저전투장 권장 쌀</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqHumanWarRecommandRice" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">유저전투장에게 주는 쌀입니다. 이보다 적으면 포상합니다. <br>
|
||||
0이면 유저전투장 긴급포상 쌀의 2배를 기준으로 하며, 그 수치는 현재 <?= number_format($autoPolicy->reqHumanWarRecommandRice) ?>입니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqHumanDevelGold" class="col-sm-6 col-form-label">유저내정장 권장 금</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqHumanDevelGold" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">유저내정장에게 주는 금입니다. 이보다 적으면 포상합니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqHumanDevelRice" class="col-sm-6 col-form-label">유저내정장 권장 쌀</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqHumanDevelRice" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">유저내정장에게 주는 쌀입니다. 이보다 적으면 포상합니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqNPCWarGold" class="col-sm-6 col-form-label">NPC전투장 권장 금</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqNPCWarGold" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">NPC전투장에게 주는 금입니다. 이보다 적으면 포상합니다. <br>
|
||||
0이면 기본 병종 4회(<?= number_format(GameConst::$defaultStatNPCMax * 100) ?> * 4) 징병비를 기준으로 하며, 그 수치는 현재 <?= number_format($autoPolicy->reqNPCWarGold) ?>입니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqNPCWarRice" class="col-sm-6 col-form-label">NPC전투장 권장 쌀</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqNPCWarRice" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">NPC전투장에게 주는 쌀입니다. 이보다 적으면 포상합니다. <br>
|
||||
0이면 기본 병종으로 <?= number_format(GameConst::$defaultStatNPCMax * 100 * 4) ?>명 사살 가능한 쌀을 기준으로 하며, 그 수치는 현재 <?= number_format($autoPolicy->reqNPCWarRice) ?>입니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqNPCDevelGold" class="col-sm-6 col-form-label">NPC내정장 권장 금</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqNPCDevelGold" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">NPC내정장에게 주는 금입니다. 이보다 5배 더 많다면 헌납합니다.<br>0이면 30턴 내정 가능한 금을 기준으로 하며, 그 수치는 현재 <?= number_format($autoPolicy->reqNPCDevelGold) ?>입니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="reqNPCDevelRice" class="col-sm-6 col-form-label">NPC내정장 권장 쌀</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="reqNPCDevelRice" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">NPC내정장에게 주는 쌀입니다. 이보다 5배 더 많다면 헌납합니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="minimumResourceActionAmount" class="col-sm-6 col-form-label">포상/몰수/헌납/삼/팜 최소 단위</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="minimumResourceActionAmount" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">연산결과가 이 단위보다 적다면 수행하지 않습니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="minWarCrew" class="col-sm-6 col-form-label">최소 전투 가능 병력 수</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="minWarCrew" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">이보다 적을 때에는 징병을 시도합니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="minNPCRecruitCityPopulation" class="col-sm-6 col-form-label">NPC 최소 징병 가능 인구 수</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="minNPCRecruitCityPopulation" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">이보다 낮으면 NPC는 도시에서 징병하지 않고 후방 워프합니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="safeRecruitCityPopulationRatio" class="col-sm-6 col-form-label">제자리 징병 허용 인구율(%)</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="percent" id="safeRecruitCityPopulationRatio" min="0" max="100" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">전쟁 시 후방 발령, 후방 워프의 기준 인구입니다. 이보다 많다면 '충분하다'고 판단합니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="minNPCWarLeadership" class="col-sm-6 col-form-label">NPC 전투 참여 통솔 기준</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="minNPCWarLeadership" min="0" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">이 수치보다 같거나 높으면 NPC전투장으로 분류됩니다.</small></div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="row">
|
||||
<label for="properWarTrainAtmos" class="col-sm-6 col-form-label">훈련/사기진작 목표치</label>
|
||||
<div class="col-sm-6">
|
||||
<input type="number" class="form-control" data-type="integer" id="properWarTrainAtmos" min="0" max="100" value="0">
|
||||
</div>
|
||||
</div>
|
||||
<div style='text-align:right;'><small class="form-text text-muted">훈련/사기진작 기준치입니다. 이보다 같거나 높으면 출병합니다.</small></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-secondary">
|
||||
전투 부대는 작업중입니다(json양식: {부대번호:[시작도시번호(아국),도착도시번호(적군)],...})<br>
|
||||
후방 징병 부대는 작업중입니다(json양식: [부대번호,...])<br>
|
||||
내정 부대는 작업중입니다(json양식: [부대번호,...])
|
||||
<input type="hidden" value="{}" data-type="json" id="CombatForce">
|
||||
<input type="hidden" value="[]" data-type="json" id="SupportForce">
|
||||
<input type="hidden" value="[]" data-type="json" id="DevelopForce">
|
||||
<input type="hidden" value="true" data-type="json" id="allowNpcAttackCity">
|
||||
<!--allowNpcAttackCity는 현재 게임 내 비활성-->
|
||||
</div>
|
||||
<div class='control_bar' data-type="nationPolicy">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-dark reset_btn">초기값으로</button>
|
||||
<button type="button" class="btn btn-secondary revert_btn">이전값으로</button>
|
||||
</div><button type="button" class="btn btn-primary submit_btn">설정</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm-6 half_section_left">
|
||||
<div class='bg1 section_bar'>NPC 사령턴 우선순위</div>
|
||||
<div class="float-right px-3"><small class="form-text text-muted">
|
||||
최근 설정: <?= $rawNationPolicy['prioritySetter'] ?? '-없음-' ?> (<?= $rawNationPolicy['prioritySetTime'] ?? '설정 기록 없음' ?>)
|
||||
</small></div>
|
||||
<div class='text-left px-2'><small class="text-muted">예턴이 없거나, 지정되어 있더라도 실패할경우<br>아래 순위에 따라 사령턴을 시도합니다.</small></div>
|
||||
<div class="form_list">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="bg2 sub_bar">비활성</div>
|
||||
<div id="nationPriorityDisabled" class="list-group col" data-type="list">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="bg2 sub_bar">활성</div>
|
||||
<div id="nationPriority" class="list-group col" data-type="list">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='control_bar' data-type="nationPriority">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-dark reset_btn">초기값으로</button>
|
||||
<button type="button" class="btn btn-secondary revert_btn">이전값으로</button>
|
||||
</div><button type="button" class="btn btn-primary submit_btn">설정</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 half_section_right">
|
||||
<div class='bg1 section_bar'>NPC 일반턴 우선순위</div>
|
||||
<div class="float-right px-3"><small class="form-text text-muted">
|
||||
최근 설정: <?= $rawNationGeneralPolicy['prioritySetter'] ?? '-없음-' ?> (<?= $rawNationGeneralPolicy['prioritySetTime'] ?? '설정 기록 없음' ?>)
|
||||
</small></div>
|
||||
<div class='text-left px-2'><small class="text-muted">순위가 높은 것부터 시도합니다. <br>아무것도 실행할 수 없으면 물자조달이나 인재탐색을 합니다.</small></div>
|
||||
<div class="form_list">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="bg2 sub_bar">비활성</div>
|
||||
<div id="generalPriorityDisabled" class="list-group col" data-type="list">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="bg2 sub_bar">활성</div>
|
||||
<div id="generalPriority" class="list-group col" data-type="list">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='control_bar' data-type="generalPriority">
|
||||
<div class="btn-group" role="group">
|
||||
<button type="button" class="btn btn-dark reset_btn">초기값으로</button>
|
||||
<button type="button" class="btn btn-secondary revert_btn">이전값으로</button>
|
||||
</div><button type="button" class="btn btn-primary submit_btn">설정</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
+6
-12
@@ -64,7 +64,7 @@ if(!$commandObj->hasPermissionToReserve()){
|
||||
die_redirect();
|
||||
}
|
||||
|
||||
$jsList = $commandObj->getJSFiles();
|
||||
$jsList = $commandObj->getJSPlugins();
|
||||
$cssList = $commandObj->getCSSFiles();
|
||||
?>
|
||||
|
||||
@@ -75,26 +75,19 @@ $cssList = $commandObj->getCSSFiles();
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/select2/select2.full.min.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printJS('d_shared/base_map.js')?>
|
||||
<?=WebUtil::printJS('js/map.js')?>
|
||||
<?=WebUtil::printJS('js/processing.js')?>
|
||||
<?=WebUtil::printJS('dist_js/processing.js')?>
|
||||
<script>
|
||||
window.serverNick = '<?=DB::prefix()?>';
|
||||
window.serverID = '<?=UniqueConst::$serverID?>';
|
||||
window.command = '<?=$commandType?>';
|
||||
window.turnList = [<?=join(', ',$turnList)?>];
|
||||
window.isChiefTurn = <?=$isChiefTurn?'true':'false'?>;
|
||||
var jsPlugins = <?=Json::encode($jsList)?>;
|
||||
</script>
|
||||
<?php
|
||||
foreach($jsList as $js){
|
||||
print(WebUtil::printJS($js));
|
||||
}
|
||||
?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/select2/select2.min.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/select2/select2-bootstrap4.css')?>
|
||||
@@ -103,6 +96,7 @@ foreach($jsList as $js){
|
||||
<?=WebUtil::printCSS('css/main.css')?>
|
||||
<?=WebUtil::printCSS('css/map.css')?>
|
||||
<?=WebUtil::printCSS('css/processing.css')?>
|
||||
|
||||
<?php
|
||||
foreach($cssList as $css){
|
||||
print(WebUtil::printCSS($css));
|
||||
|
||||
@@ -145,7 +145,7 @@ if($str3){
|
||||
?>
|
||||
<tr><td colspan=8>운영자 메세지 : <font color=orange size=5><?=$admin['tnmt_msg']?></font></td></tr>
|
||||
<tr><td colspan=8 align=center><font color=white size=6><?=$tnmt_type?> (<?=$str1.$str2.$str3?>)</font></td></tr>
|
||||
<tr><td colspan=8 align=center id=bg2><font color=magenta size=5>16강 승자전</font></td></tr>
|
||||
<tr><td colspan=8 align=center class='bg2'><font color=magenta size=5>16강 승자전</font></td></tr>
|
||||
<tr><td height=10 colspan=8 align=center></td></tr>
|
||||
<?php
|
||||
|
||||
@@ -398,7 +398,7 @@ if ($admin['tournament'] >= 7 || $admin['tournament'] == 0) {
|
||||
}
|
||||
echo "
|
||||
<tr><td height=10 colspan=8 align=center></td></tr>
|
||||
<tr><td colspan=8 align=center id=bg2><font color=orange size=5>조별 본선 순위</font></td></tr>
|
||||
<tr><td colspan=8 align=center class='bg2'><font color=orange size=5>조별 본선 순위</font></td></tr>
|
||||
<tr>";
|
||||
|
||||
$num = array("一", "二", "三", "四", "五", "六", "七", "八");
|
||||
@@ -409,7 +409,7 @@ for ($i=0; $i < 8; $i++) {
|
||||
<td>
|
||||
<table align=center width=250 class='tb_layout bg0'>
|
||||
<tr><td colspan=9 style=background-color:black;>{$num[$i]}조</td></tr>
|
||||
<tr id=bg1><td align=center>순</td><td align=center>장수</td><td align=center>{$tp2}</td><td align=center>경</td><td align=center>승</td><td align=center>무</td><td align=center>패</td><td align=center>점</td><td align=center>득</td></tr>";
|
||||
<tr class='bg1'><td align=center>순</td><td align=center>장수</td><td align=center>{$tp2}</td><td align=center>경</td><td align=center>승</td><td align=center>무</td><td align=center>패</td><td align=center>점</td><td align=center>득</td></tr>";
|
||||
|
||||
$generalList = $db->query('SELECT npc,name,leadership,strength,intel,leadership+strength+intel as total,prmt,win+draw+lose as game,win,draw,lose,gl,win*3+draw as gd from tournament where grp=%i order by gd desc, gl desc, seq',$grp);
|
||||
foreach($generalList as $k=>$general) {
|
||||
@@ -427,7 +427,7 @@ if ($admin['tournament'] == 4 || $admin['tournament'] == 5) {
|
||||
printFighting($admin['tournament'], $admin['phase']);
|
||||
}
|
||||
echo "
|
||||
<tr><td colspan=8 align=center id=bg2><font color=yellow size=5>조별 예선 순위</font></td></tr>
|
||||
<tr><td colspan=8 align=center class='bg2'><font color=yellow size=5>조별 예선 순위</font></td></tr>
|
||||
<tr>";
|
||||
|
||||
for ($i=0; $i < 8; $i++) {
|
||||
@@ -436,7 +436,7 @@ for ($i=0; $i < 8; $i++) {
|
||||
<td>
|
||||
<table align=center width=250 class='tb_layout bg0'>
|
||||
<tr><td colspan=9 style=background-color:black;>{$num[$i]}조</td></tr>
|
||||
<tr id=bg1><td align=center>순</td><td align=center>장수</td><td align=center>{$tp2}</td><td align=center>경</td><td align=center>승</td><td align=center>무</td><td align=center>패</td><td align=center>점</td><td align=center>득</td></tr>";
|
||||
<tr class='bg1'><td align=center>순</td><td align=center>장수</td><td align=center>{$tp2}</td><td align=center>경</td><td align=center>승</td><td align=center>무</td><td align=center>패</td><td align=center>점</td><td align=center>득</td></tr>";
|
||||
|
||||
$generalList = $db->query('SELECT npc,name,leadership,strength,intel,leadership+strength+intel as total,prmt,win+draw+lose as game,win,draw,lose,gl,win*3+draw as gd from tournament where grp=%i order by gd desc, gl desc, seq',$grp);
|
||||
foreach($generalList as $k=>$general) {
|
||||
|
||||
+10
-11
@@ -44,7 +44,7 @@ if($troops){
|
||||
$generalTurnList = [];
|
||||
|
||||
foreach($db->queryAllLists(
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
|
||||
array_column($troopLeaders, 'no')
|
||||
) as [$generalID, $turnIdx, $brief]
|
||||
){
|
||||
@@ -53,10 +53,10 @@ if($troops){
|
||||
}
|
||||
$generalTurnList[$generalID][$turnIdx] = $brief;
|
||||
}
|
||||
|
||||
|
||||
foreach($troopLeaders as $troopLeader){
|
||||
$imageTemp = GetImageURL($troopLeader['imgsvr']);
|
||||
|
||||
|
||||
$troopLeader['pictureFullPath'] = "$imageTemp/{$troopLeader['picture']}";
|
||||
$troopLeader['cityText'] = CityConst::byID($troopLeader['city'])->name;
|
||||
|
||||
@@ -85,15 +85,14 @@ uasort($troops, function($lhs, $rhs){
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<title><?=UniqueConst::$serverName?>: 부대편성</title>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/troop.js')?>
|
||||
<?=WebUtil::printJS('js/ext.plugin_troop.js')?>
|
||||
<?=WebUtil::preloadJS('dist_js/troop.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/common.js')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printCSS('css/troops.css')?>
|
||||
<?=WebUtil::printCSS('dist_css/troop.css')?>
|
||||
<script>
|
||||
|
||||
</script>
|
||||
@@ -195,7 +194,7 @@ foreach ($troops as $troopNo=>$troop) {
|
||||
<br>
|
||||
<table width=1000 class='tb_layout bg0'>
|
||||
<tr>
|
||||
<td width=80 id=bg1>부 대 명</td>
|
||||
<td width=80 class='bg1'>부 대 명</td>
|
||||
<td width=130><input type=text style=color:white;background-color:black; size=18 maxlength=18 id='nameplate'></td>
|
||||
<?php if($me['troop'] == 0): ?>
|
||||
<td><input type=button id='btnCreateTroop' value='부 대 창 설'></td>
|
||||
@@ -210,6 +209,6 @@ foreach ($troops as $troopNo=>$troop) {
|
||||
<tr><td><?=banner()?> </td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<?=WebUtil::printJS('dist_js/troop.js')?>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
+547
-480
@@ -1,481 +1,548 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$session = Session::requireLogin()->setReadOnly();
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$startYear = $gameStor->getValue('startyear');
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?=UniqueConst::$serverName?>: 전투 시뮬레이터</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1100" />
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printCSS('css/battle_simulator.css')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/moment.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/download2.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<script>
|
||||
var defaultSpecialDomestic = '<?=GameConst::$defaultSpecialDomestic?>';
|
||||
</script>
|
||||
<?=WebUtil::printJS('js/battle_simulator.js')?>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
전역 설정
|
||||
</div>
|
||||
<div class="card-body dragpad_battle">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" aria-describedby="text_year" value="<?=$startYear?>" disabled>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">년 시작</span>
|
||||
</div>
|
||||
<input type="number" class="form-control" id="year" value="<?=$startYear+3?>" min="<?=$startYear?>">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">년</span>
|
||||
</div>
|
||||
<input type="number" class="form-control" id="month" value="1" min="1" max="12">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">월</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="input-group mr-2" role="group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">반복 횟수</span>
|
||||
</div>
|
||||
<select class="custom-select" id="repeat_cnt">
|
||||
<option value="1">1회 (로그 표기)</option>
|
||||
<option value="1000">1000회 (요약 표기)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="btn-group mr-2" role="group">
|
||||
<button type="button" class="btn btn-danger btn-begin_battle">전투</button>
|
||||
</div>
|
||||
<div class="btn-group mr-2" role="group">
|
||||
<button type="button" class="btn btn-info btn-battle-save">모두 저장</button>
|
||||
<input type="file" class="form_load_battle_file" accept=".json" style="display: none;" />
|
||||
<button type="button" class="btn btn-primary btn-battle-load">모두 불러오기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="card mb-2 attacker_nation">
|
||||
<div class="card-header">
|
||||
출병국 설정
|
||||
</div>
|
||||
<div class="card-body nation_detail dragpad_battle">
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 성향</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_type" style="width:25ch;">
|
||||
<?php foreach(GameConst::$availableNationType as $typeID): ?>
|
||||
<?php $nationTypeClass = buildNationTypeClass($typeID) ?>
|
||||
<option value="<?=$typeID?>"><?=$nationTypeClass->getName()?> (<?=$nationTypeClass::$pros?>, <?=$nationTypeClass::$cons?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">기술</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_tech" value="1" min="0" max="12">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">등급</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_level">
|
||||
<?php foreach(getNationLevelList() as $nationLevel => [$name,$chiefCnt,$cityCnt]): ?>
|
||||
<option value="<?=$nationLevel?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">도시 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_city_level">
|
||||
<?php foreach(getCityLevelList() as $levelID => $name): ?>
|
||||
<option value="<?=$levelID?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">수도</span>
|
||||
</div>
|
||||
<div class="input-group-append btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="is_attacker_capital" class="form_is_capital" value="1" autocomplete="off">Y
|
||||
</label>
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="is_attacker_capital" class="form_is_capital" value="2" autocomplete="off" checked>N
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 attacker_form general_form" data-general_no='1'>
|
||||
<div class="card-header">
|
||||
<div class="float-sm-left" style="line-height:25px;">출병자 설정</div>
|
||||
<div class="float-sm-right btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-info btn-general-save">저장</button>
|
||||
<input type="file" class="form_load_general_file" accept=".json" style="display: none;" />
|
||||
<button type="button" class="btn btn-primary btn-general-load">불러오기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- <div class="col-sm"> -->
|
||||
<div class="col-sm defender-column">
|
||||
<div class="card mb-2 defender_nation">
|
||||
<div class="card-header">
|
||||
수비국 설정
|
||||
</div>
|
||||
<div class="card-body dragpad_battle">
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 성향</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_type" style="width:25ch;">
|
||||
<?php foreach(GameConst::$availableNationType as $typeID): ?>
|
||||
<?php $nationTypeObj = buildNationTypeClass($typeID) ?>
|
||||
<option value="<?=$typeID?>"><?=$nationTypeObj->getName()?> (<?=$nationTypeObj::$pros?>, <?=$nationTypeObj::$cons?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">기술</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_tech" value="1" min="0" max="12">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">등급</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_level">
|
||||
<?php foreach(getNationLevelList() as $nationLevel => [$name,$chiefCnt,$cityCnt]): ?>
|
||||
<option value="<?=$nationLevel?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">도시 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_city_level">
|
||||
<?php foreach(getCityLevelList() as $levelID => $name): ?>
|
||||
<option value="<?=$levelID?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">수도</span>
|
||||
</div>
|
||||
<div class="input-group-append btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="is_defender_capital" class="form_is_capital" value="1" autocomplete="off">Y
|
||||
</label>
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="is_defender_capital" class="form_is_capital" value="0" autocomplete="off" checked>N
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">수비</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_def" id="city_def" value="1000" min="10" step="10">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">성벽</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_wall" id="city_wall" value="1000" min="0" step="10">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 defender_add_form">
|
||||
<div class="card-header">
|
||||
<div class="float-sm-left" style="line-height:25px;">수비자 설정</div>
|
||||
<div class="float-sm-right btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-dark btn-reorder_defender">수비 순서대로 정렬</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-success add-defender">추가</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 form_sample">
|
||||
<div class="card-header">
|
||||
<div class="float-sm-left" style="line-height:25px;">수비자 설정</div>
|
||||
<div class="float-sm-right btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-info btn-general-save">저장</button>
|
||||
<input type="file" class="form_load_general_file" accept=".json" style="display: none;" />
|
||||
<button type="button" class="btn btn-primary btn-general-load">불러오기</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-warning copy-defender">복제</button>
|
||||
<button type="button" class="btn btn-danger delete-defender">제거</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body general_detail">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">이름</span>
|
||||
</div>
|
||||
<input type="text" class="form-control form_general_name" value="무명" style="width:15ch;">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">직위</span>
|
||||
</div>
|
||||
<select class="custom-select form_officer_level" style="width:8ch;">
|
||||
<option value="1">일반</option>
|
||||
<option value="4">태수</option>
|
||||
<option value="3">군사</option>
|
||||
<option value="2">종사</option>
|
||||
<option value="10">무장 수뇌</option>
|
||||
<option value="9">지장 수뇌</option>
|
||||
<option value="11">참모</option>
|
||||
<option value="12">군주</option>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Level</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_exp_level" value="20" min="0" max="300" step="1">
|
||||
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">통솔</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_leadership" value="50" min="1" max="300" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">무력</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_strength" value="50" min="1" max="300" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">지력</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_intel" value="50" min="1" max="300" step="1">
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">명마</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_horse">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['horse'] as $horseID=>$cnt): ?>
|
||||
<option value="<?=$horseID?>"><?=getItemName($horseID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">무기</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_weap">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['weapon'] as $weaponID=>$cnt): ?>
|
||||
<option value="<?=$weaponID?>"><?=getItemName($weaponID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">서적</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_book">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['book'] as $bookID=>$cnt): ?>
|
||||
<option value="<?=$bookID?>"><?=getItemName($bookID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">부상</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_injury" value="0" min="0" max="80" step="1">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%(<span class="injury_helptext">건강</span>)</span>
|
||||
</div>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">군량</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_rice" value="5000" min="50" max="40000" step="50">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">도구</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_item">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['item'] as $itemID=>$cnt): ?>
|
||||
<option value="<?=$itemID?>"><?=getItemName($itemID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">병종</span>
|
||||
</div>
|
||||
<select class="custom-select form_crewtype">
|
||||
<?php foreach(GameUnitConst::all() as $crewTypeID => $crewType): ?>
|
||||
<?php if($crewType->armType === GameUnitConst::T_CASTLE){ continue; } ?>
|
||||
<option value="<?=$crewTypeID?>"><?=$crewType->name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">병사</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_crew" value="7000" min="100" step="100">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">성격</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_character">
|
||||
<?php foreach(getCharacterList(false) as $characterID => [$name,$info]): ?>
|
||||
<option value="<?=$characterID?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">훈련</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_train" value="100" min="40" max="<?=GameConst::$maxTrainByWar?>" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">사기</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_atmos" value="100" min="40" max="<?=GameConst::$maxAtmosByWar?>" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">전특</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_special_war">
|
||||
<?php foreach(SpecialityHelper::getSpecialWarList(false) as $specialWarID =>$specialObj): ?>
|
||||
<option value="<?=$specialWarID?>"><?=$specialObj->getName()?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">보병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex1">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">궁병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex2">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">기병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex3">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">귀병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex4">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">차병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex5">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend only_defender">
|
||||
<span class="input-group-text">수비여부</span>
|
||||
</div>
|
||||
<select class="custom-select form_defence_train only_defender">
|
||||
<option value="80">훈사 80</option>
|
||||
<option value="60">훈사 60</option>
|
||||
<option value="999">안함</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div><!-- <div class="col-sm"> -->
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
전투 요약
|
||||
</div>
|
||||
<table class="table">
|
||||
<tbody id="battle_result_summary">
|
||||
<tr><th style='width:18ch;'>전투 일시</th><td id='result_datetime'></td></tr>
|
||||
<tr><th>전투 횟수</th><td id='result_warcnt'></td></tr>
|
||||
<tr><th>전투 페이즈</th><td id='result_phase'></td></tr>
|
||||
<tr><th>준 피해</th><td><span id='result_killed'>0</span><span id='result_varKilled'> (<span id='result_minKilled'>0</span> ~ <span id='result_maxKilled'>0</span>)</span></td></tr>
|
||||
<tr><th>받은 피해</th><td><span id='result_dead'>0</span><span id='result_varDead'> (<span id='result_minDead'>0</span> ~ <span id='result_maxDead'>0</span>)</span></td></tr>
|
||||
<tr><th>출병자 군량 소모</th><td id='result_attackerRice'></td></tr>
|
||||
<tr><th>수비자 군량 소모</th><td id='result_defenderRice'></td></tr>
|
||||
<tr><th>공격자 스킬</th><td id='result_attackerSkills'></td></tr>
|
||||
<tr class='result_defenderSkills'><th>수비자1 스킬</th><td></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
마지막 전투 로그
|
||||
</div>
|
||||
<div class="card-body" id="generalBattleResultLog">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
마지막 전투 상세 로그
|
||||
</div>
|
||||
<div class="card-body" id="generalBattleDetailLog">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
$session = Session::requireLogin()->setReadOnly();
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$gameStor->cacheValues(['startyear', 'year']);
|
||||
$startYear = $gameStor->startyear;
|
||||
$year = $gameStor->year;
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no, nation, city FROM general WHERE owner =%i', Session::getUserID());
|
||||
|
||||
if($me){
|
||||
$generalID = $me['no'];
|
||||
$nationID = $me['nation'];
|
||||
$city = $db->queryFirstRow('SELECT city, level, def, wall FROM city WHERE city = %i', $me['city']);
|
||||
}
|
||||
else{
|
||||
$generalID = 0;
|
||||
$nationID = 0;
|
||||
$city = [
|
||||
'city'=>0,
|
||||
'level'=>5,
|
||||
'def'=>1000,
|
||||
'wall'=>1000,
|
||||
];
|
||||
}
|
||||
|
||||
if($nationID){
|
||||
$nation = $db->queryFirstRow('SELECT level, type, tech, capital FROM nation WHERE nation = %i', $nationID);
|
||||
}
|
||||
else{
|
||||
$nation = null;
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title><?=UniqueConst::$serverName?>: 전투 시뮬레이터</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1100" />
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('../d_shared/common.css')?>
|
||||
<?=WebUtil::printCSS('css/common.css')?>
|
||||
<?=WebUtil::printCSS('css/battle_simulator.css')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<script>
|
||||
var defaultSpecialDomestic = '<?=GameConst::$defaultSpecialDomestic?>';
|
||||
var city = <?=Json::encode($city)?>;
|
||||
var nation = <?=Json::encode($nation)?>;
|
||||
</script>
|
||||
<?=WebUtil::printJS('dist_js/battle_simulator.js')?>
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
전역 설정
|
||||
</div>
|
||||
<div class="card-body dragpad_battle">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" aria-describedby="text_year" value="<?=$startYear?>" disabled>
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">년 시작</span>
|
||||
</div>
|
||||
<input type="number" class="form-control" id="year" value="<?=$year?>" min="<?=$startYear?>">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">년</span>
|
||||
</div>
|
||||
<input type="number" class="form-control" id="month" value="1" min="1" max="12">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">월</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="input-group mr-2" role="group">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">반복 횟수</span>
|
||||
</div>
|
||||
<select class="custom-select" id="repeat_cnt">
|
||||
<option value="1">1회 (로그 표기)</option>
|
||||
<option value="1000">1000회 (요약 표기)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="btn-group mr-2" role="group">
|
||||
<button type="button" class="btn btn-danger btn-begin_battle">전투</button>
|
||||
</div>
|
||||
<div class="btn-group mr-2" role="group">
|
||||
<button type="button" class="btn btn-info btn-battle-save">모두 저장</button>
|
||||
<input type="file" class="form_load_battle_file" accept=".json" style="display: none;" />
|
||||
<button type="button" class="btn btn-primary btn-battle-load">모두 불러오기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="card mb-2 attacker_nation">
|
||||
<div class="card-header">
|
||||
출병국 설정
|
||||
</div>
|
||||
<div class="card-body nation_detail dragpad_battle">
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 성향</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_type" style="width:25ch;">
|
||||
<?php foreach(GameConst::$availableNationType as $typeID): ?>
|
||||
<?php $nationTypeClass = buildNationTypeClass($typeID) ?>
|
||||
<option value="<?=$typeID?>"><?=$nationTypeClass->getName()?> (<?=$nationTypeClass::$pros?>, <?=$nationTypeClass::$cons?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">기술</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_tech" value="1" min="0" max="12">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">등급</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_level">
|
||||
<?php foreach(getNationLevelList() as $nationLevel => [$name,$chiefCnt,$cityCnt]): ?>
|
||||
<option value="<?=$nationLevel?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">도시 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_city_level">
|
||||
<?php foreach(getCityLevelList() as $levelID => $name): ?>
|
||||
<option value="<?=$levelID?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">수도</span>
|
||||
</div>
|
||||
<div class="input-group-append btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="is_attacker_capital" class="form_is_capital" value="1" autocomplete="off">Y
|
||||
</label>
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="is_attacker_capital" class="form_is_capital" value="0" autocomplete="off">N
|
||||
</label>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 attacker_form general_form" data-general_no='1'>
|
||||
<div class="card-header">
|
||||
<div class="float-sm-left" style="line-height:25px;">출병자 설정</div>
|
||||
<div class="float-sm-right btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-success btn-general-import-server">서버에서 가져오기</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-info btn-general-save">저장</button>
|
||||
<input type="file" class="form_load_general_file" accept=".json" style="display: none;" />
|
||||
<button type="button" class="btn btn-primary btn-general-load">불러오기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- <div class="col-sm"> -->
|
||||
<div class="col-sm defender-column">
|
||||
<div class="card mb-2 defender_nation">
|
||||
<div class="card-header">
|
||||
수비국 설정
|
||||
</div>
|
||||
<div class="card-body dragpad_battle">
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 성향</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_type" style="width:25ch;">
|
||||
<?php foreach(GameConst::$availableNationType as $typeID): ?>
|
||||
<?php $nationTypeObj = buildNationTypeClass($typeID) ?>
|
||||
<option value="<?=$typeID?>"><?=$nationTypeObj->getName()?> (<?=$nationTypeObj::$pros?>, <?=$nationTypeObj::$cons?>)</option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">기술</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_tech" value="1" min="0" max="12">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">등급</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">국가 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_nation_level">
|
||||
<?php foreach(getNationLevelList() as $nationLevel => [$name,$chiefCnt,$cityCnt]): ?>
|
||||
<option value="<?=$nationLevel?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">도시 규모</span>
|
||||
</div>
|
||||
<select class="custom-select form_city_level">
|
||||
<?php foreach(getCityLevelList() as $levelID => $name): ?>
|
||||
<option value="<?=$levelID?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">수도</span>
|
||||
</div>
|
||||
<div class="input-group-append btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="is_defender_capital" class="form_is_capital" value="1" autocomplete="off">Y
|
||||
</label>
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="is_defender_capital" class="form_is_capital" value="0" autocomplete="off">N
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">수비</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_def" id="city_def" value="1000" min="10" step="10">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">성벽</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_wall" id="city_wall" value="1000" min="0" step="10">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 defender_add_form">
|
||||
<div class="card-header">
|
||||
<div class="float-sm-left" style="line-height:25px;">수비자 설정</div>
|
||||
<div class="float-sm-right btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-dark btn-reorder_defender">수비 순서대로 정렬</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-success add-defender">추가</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 form_sample">
|
||||
<div class="card-header">
|
||||
<div class="float-sm-left" style="line-height:25px;">수비자 설정</div>
|
||||
<div class="float-sm-right btn-toolbar" role="toolbar">
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-success btn-general-import-server">서버에서 가져오기</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm mr-2" role="group">
|
||||
<button type="button" class="btn btn-info btn-general-save">저장</button>
|
||||
<input type="file" class="form_load_general_file" accept=".json" style="display: none;" />
|
||||
<button type="button" class="btn btn-primary btn-general-load">불러오기</button>
|
||||
</div>
|
||||
<div class="btn-group btn-group-sm" role="group">
|
||||
<button type="button" class="btn btn-warning copy-defender">복제</button>
|
||||
<button type="button" class="btn btn-danger delete-defender">제거</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-body general_detail">
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">이름</span>
|
||||
</div>
|
||||
<input type="text" class="form-control form_general_name" value="무명" style="width:15ch;">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">직위</span>
|
||||
</div>
|
||||
<select class="custom-select form_officer_level" style="width:8ch;">
|
||||
<option value="1">일반</option>
|
||||
<option value="4">태수</option>
|
||||
<option value="3">군사</option>
|
||||
<option value="2">종사</option>
|
||||
<option value="10">무장 수뇌</option>
|
||||
<option value="9">지장 수뇌</option>
|
||||
<option value="11">참모</option>
|
||||
<option value="12">군주</option>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">Level</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_exp_level" value="20" min="0" max="300" step="1">
|
||||
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">통솔</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_leadership" value="50" min="1" max="300" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">무력</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_strength" value="50" min="1" max="300" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">지력</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_intel" value="50" min="1" max="300" step="1">
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">명마</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_horse">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['horse'] as $horseID=>$cnt): ?>
|
||||
<option value="<?=$horseID?>"><?=getItemName($horseID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">무기</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_weap">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['weapon'] as $weaponID=>$cnt): ?>
|
||||
<option value="<?=$weaponID?>"><?=getItemName($weaponID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">서적</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_book">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['book'] as $bookID=>$cnt): ?>
|
||||
<option value="<?=$bookID?>"><?=getItemName($bookID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">부상</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_injury" value="0" min="0" max="80" step="1">
|
||||
<div class="input-group-append">
|
||||
<span class="input-group-text">%(<span class="injury_helptext">건강</span>)</span>
|
||||
</div>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">군량</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_rice" value="5000" min="50" max="40000" step="50">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">도구</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_item">
|
||||
<option value='None'>-</option>
|
||||
<?php foreach(GameConst::$allItems['item'] as $itemID=>$cnt): ?>
|
||||
<option value="<?=$itemID?>"><?=getItemName($itemID)?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">병종</span>
|
||||
</div>
|
||||
<select class="custom-select form_crewtype">
|
||||
<?php foreach(GameUnitConst::all() as $crewTypeID => $crewType): ?>
|
||||
<?php if($crewType->armType === GameUnitConst::T_CASTLE){ continue; } ?>
|
||||
<option value="<?=$crewTypeID?>"><?=$crewType->name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">병사</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_crew" value="7000" min="100" step="100">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">성격</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_character">
|
||||
<?php foreach(getCharacterList(false) as $characterID => [$name,$info]): ?>
|
||||
<option value="<?=$characterID?>"><?=$name?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">훈련</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_train" value="100" min="40" max="<?=GameConst::$maxTrainByWar?>" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">사기</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_atmos" value="100" min="40" max="<?=GameConst::$maxAtmosByWar?>" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">전특</span>
|
||||
</div>
|
||||
<select class="custom-select form_general_special_war">
|
||||
<?php foreach(SpecialityHelper::getSpecialWarList(false) as $specialWarID =>$specialObj): ?>
|
||||
<option value="<?=$specialWarID?>"><?=$specialObj->getName()?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">보병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex1">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">궁병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex2">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">기병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex3">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-3">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">귀병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex4">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">차병숙련</span>
|
||||
</div>
|
||||
<select class="custom-select form_dex5">
|
||||
<?php foreach(getDexLevelList() as $dexLevel => [$dexAmount, $color, $name]): ?>
|
||||
<option value="<?=$dexAmount?>"><?="{$name} (".number_format($dexAmount).")"?></option>
|
||||
<?php endforeach; ?>
|
||||
</select>
|
||||
<div class="input-group-prepend only_defender">
|
||||
<span class="input-group-text">수비여부</span>
|
||||
</div>
|
||||
<select class="custom-select form_defence_train only_defender">
|
||||
<option value="90">훈사 90</option>
|
||||
<option value="80">훈사 80</option>
|
||||
<option value="60">훈사 60</option>
|
||||
<option value="40">훈사 40</option>
|
||||
<option value="999">안함</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">전투 수</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_warnum" value="0" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">승리 수</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_killnum" value="0" step="1">
|
||||
<div class="input-group-prepend">
|
||||
<span class="input-group-text">사살 수</span>
|
||||
</div>
|
||||
<input type="number" class="form-control form_killcrew" value="0" step="1">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div><!-- <div class="col-sm"> -->
|
||||
</div>
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
전투 요약
|
||||
</div>
|
||||
<table class="table">
|
||||
<tbody id="battle_result_summary">
|
||||
<tr><th style='width:18ch;'>전투 일시</th><td id='result_datetime'></td></tr>
|
||||
<tr><th>전투 횟수</th><td id='result_warcnt'></td></tr>
|
||||
<tr><th>전투 페이즈</th><td id='result_phase'></td></tr>
|
||||
<tr><th>준 피해</th><td><span id='result_killed'>0</span><span id='result_varKilled'> (<span id='result_minKilled'>0</span> ~ <span id='result_maxKilled'>0</span>)</span></td></tr>
|
||||
<tr><th>받은 피해</th><td><span id='result_dead'>0</span><span id='result_varDead'> (<span id='result_minDead'>0</span> ~ <span id='result_maxDead'>0</span>)</span></td></tr>
|
||||
<tr><th>출병자 군량 소모</th><td id='result_attackerRice'></td></tr>
|
||||
<tr><th>수비자 군량 소모</th><td id='result_defenderRice'></td></tr>
|
||||
<tr><th>공격자 스킬</th><td id='result_attackerSkills'></td></tr>
|
||||
<tr class='result_defenderSkills'><th>수비자1 스킬</th><td></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-sm">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
마지막 전투 로그
|
||||
</div>
|
||||
<div class="card-body" id="generalBattleResultLog">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm">
|
||||
<div class="card mb-3">
|
||||
<div class="card-header">
|
||||
마지막 전투 상세 로그
|
||||
</div>
|
||||
<div class="card-body" id="generalBattleDetailLog">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="importModal" class="modal" tabindex="-1" role="dialog">
|
||||
<div class="modal-dialog" role="document">
|
||||
<div class="modal-content">
|
||||
<div class="modal-header">
|
||||
<h5 class="modal-title">장수 목록</h5>
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<select id="modalSelector"></select>
|
||||
<p>타국 장수를 선택한 경우 숙련과 아이템은 0으로 초기화됩니다.</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-primary" id='importFromDB'>가져오기</button>
|
||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">닫기</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
+1
-2
@@ -7,7 +7,7 @@ include "func.php";
|
||||
|
||||
$btn = Util::getPost('btn');
|
||||
$msg = Util::getPost('msg');
|
||||
$scoutmsg = Util::getPost('scoutmsg');
|
||||
$scoutmsg = Util::getPost('scoutMsg');
|
||||
$rate = Util::getPost('rate', 'int');
|
||||
$bill = Util::getPost('bill', 'int');
|
||||
$secretlimit = Util::getPost('secretlimit', 'int');
|
||||
@@ -75,4 +75,3 @@ if($btn == "국가방침 수정") {
|
||||
}
|
||||
|
||||
header('location:b_dipcenter.php');
|
||||
|
||||
|
||||
+2
-2
@@ -15,7 +15,7 @@ $session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$isVoteAdmin = in_array('vote', $session->acl[DB::prefix()]??[]);
|
||||
$isVoteAdmin |= $session->userGrade >= 5;
|
||||
$isVoteAdmin = $isVoteAdmin || $session->userGrade >= 5;
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
@@ -24,7 +24,7 @@ $admin = $gameStor->getValues(['develcost', 'cost', 'vote_title', 'vote', 'votec
|
||||
|
||||
$generalID = Session::getGeneralID();
|
||||
|
||||
$general = General::createGeneralObjFromDB($generalID, ['vote','horse','weapon','book','item','npc'], 2);
|
||||
$general = General::createGeneralObjFromDB($generalID, ['vote','horse','weapon','book','item','npc','imgsvr','picture','aux'], 2);
|
||||
|
||||
if($btn == "투표" && $general->getVar('vote') == 0 && $sel > 0) {
|
||||
$develcost = $admin['develcost'] * 5;
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
#newArticle{
|
||||
width:1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.titleInput{
|
||||
width:100%;
|
||||
color:white;
|
||||
background-color:transparent;
|
||||
border:none;
|
||||
margin:1px 5px;
|
||||
}
|
||||
|
||||
.contentInput{
|
||||
width:100%;
|
||||
min-height:3em;
|
||||
color:white;
|
||||
background-color:transparent;
|
||||
border:none;
|
||||
padding:1px 5px;
|
||||
}
|
||||
|
||||
.articleFrame{
|
||||
width:1000px;
|
||||
margin: 20px auto;
|
||||
}
|
||||
|
||||
.commentText{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.authorName, .comment .author{
|
||||
width:110px;
|
||||
font-size:85%;
|
||||
}
|
||||
|
||||
.date{
|
||||
width:125px;
|
||||
font-size:85%;
|
||||
}
|
||||
|
||||
.text{
|
||||
text-align:left;
|
||||
padding:1px 5px;
|
||||
}
|
||||
|
||||
.submitComment{
|
||||
width:100%;
|
||||
}
|
||||
|
||||
.commentText{
|
||||
color:white;
|
||||
background-color:transparent;
|
||||
border:none;
|
||||
padding:1px 5px;
|
||||
}
|
||||
+155
-135
@@ -1,40 +1,56 @@
|
||||
@charset "UTF-8";
|
||||
|
||||
/* font-boostring Block */
|
||||
html * {max-height:1000000px;}
|
||||
|
||||
|
||||
html, body{
|
||||
background-color:black;
|
||||
color:white;
|
||||
line-height:1.3;
|
||||
font-family:'맑은 고딕';
|
||||
font-size:13px;
|
||||
html * {
|
||||
max-height: 1000000px;
|
||||
}
|
||||
|
||||
table { font-family:'맑은 고딕'; }
|
||||
font { font-family:'맑은 고딕'; }
|
||||
input { font-family:'맑은 고딕'; font-size:13px; }
|
||||
select { font-family:'굴림'; line-height:100%; }
|
||||
|
||||
.center{
|
||||
text-align:center;
|
||||
html,
|
||||
body {
|
||||
background-color: black;
|
||||
color: white;
|
||||
line-height: 1.3;
|
||||
font-family: '맑은 고딕';
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
table.mimic_flex{
|
||||
table {
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
font {
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
input {
|
||||
font-family: '맑은 고딕';
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
select {
|
||||
font-family: '굴림';
|
||||
line-height: 100%;
|
||||
}
|
||||
|
||||
.center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
table.mimic_flex {
|
||||
border-collapse: collapse;
|
||||
border:none;
|
||||
padding:0;
|
||||
border: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.mimic_flex td, .mimic_flex th {
|
||||
border:none !important;
|
||||
.mimic_flex td,
|
||||
.mimic_flex th {
|
||||
border: none !important;
|
||||
padding: 0px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
|
||||
table.tb_layout {
|
||||
table.tb_layout {
|
||||
border-collapse: collapse;
|
||||
padding: 0px;
|
||||
font-size: 13px;
|
||||
@@ -42,159 +58,161 @@ table.tb_layout {
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
.tb_layout td, .tb_layout th {
|
||||
border:solid 1px gray;
|
||||
.tb_layout td,
|
||||
.tb_layout th {
|
||||
border: solid 1px gray;
|
||||
padding: 0px;
|
||||
word-break: break-all;
|
||||
font-family: '맑은 고딕';;
|
||||
font-family: '맑은 고딕';
|
||||
;
|
||||
}
|
||||
|
||||
div.bar_out{
|
||||
position:relative;
|
||||
border-top:solid 1px #888888;
|
||||
border-bottom:solid 1px #333333;
|
||||
padding:0;
|
||||
margin:0;
|
||||
width:100%;
|
||||
div.bar_out {
|
||||
position: relative;
|
||||
border-top: solid 1px #888888;
|
||||
border-bottom: solid 1px #333333;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.bar_out div{
|
||||
position:absolute;
|
||||
left:0;
|
||||
top:0;
|
||||
height:100%;
|
||||
div.bar_out div {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div.bar_out div.bar_in{
|
||||
width:100%;
|
||||
div.bar_out div.bar_in {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
|
||||
/* */
|
||||
|
||||
.ev_warning{
|
||||
color:orangered;
|
||||
.ev_warning {
|
||||
color: orangered;
|
||||
}
|
||||
|
||||
.ev_notice{
|
||||
color:orangered;
|
||||
.ev_notice {
|
||||
color: orangered;
|
||||
}
|
||||
|
||||
.ev_succes{
|
||||
color:lightgreen;
|
||||
.ev_succes {
|
||||
color: lightgreen;
|
||||
}
|
||||
|
||||
.ev_sell{
|
||||
color:orange;
|
||||
.ev_sell {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.ev_failed{
|
||||
color:orangered;
|
||||
.ev_failed {
|
||||
color: orangered;
|
||||
}
|
||||
|
||||
.ev_highlight{
|
||||
color:orangered;
|
||||
.ev_highlight {
|
||||
color: orangered;
|
||||
}
|
||||
|
||||
|
||||
/* TODO: 색상값이 아니라 의미에 따라 클래스 지정 */
|
||||
|
||||
.o_bullet::before{
|
||||
color:cyan;
|
||||
content:"●";
|
||||
.o_bullet::before {
|
||||
color: cyan;
|
||||
content: "●";
|
||||
}
|
||||
|
||||
.o_diamond::before{
|
||||
color:orangered;
|
||||
content:"◆";
|
||||
.o_diamond::before {
|
||||
color: orangered;
|
||||
content: "◆";
|
||||
}
|
||||
|
||||
.small_war_log{
|
||||
display:inline-block;
|
||||
.small_war_log {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.small_war_log .war_type_attack{
|
||||
color:cyan;
|
||||
.small_war_log .war_type_attack {
|
||||
color: cyan;
|
||||
}
|
||||
|
||||
.small_war_log .war_type_defense{
|
||||
color:magenta;
|
||||
.small_war_log .war_type_defense {
|
||||
color: magenta;
|
||||
}
|
||||
|
||||
.small_war_log .war_type_siege{
|
||||
color:white;
|
||||
.small_war_log .war_type_siege {
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.small_war_log .name_plate{
|
||||
.small_war_log .name_plate {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.small_war_log .name_plate_cover{
|
||||
color:yellow;
|
||||
.small_war_log .name_plate_cover {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
.small_war_log .crew_plate{
|
||||
color:orangered;
|
||||
font-size:90%;
|
||||
.small_war_log .crew_plate {
|
||||
color: orangered;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.t_date{
|
||||
.t_date {
|
||||
font-size: 0.75em;
|
||||
}
|
||||
|
||||
.t_red{
|
||||
color:red;
|
||||
.t_red {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.t_blue{
|
||||
color:blue;
|
||||
.t_blue {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.t_green{
|
||||
color:green;
|
||||
.t_green {
|
||||
color: green;
|
||||
}
|
||||
|
||||
.t_magenta{
|
||||
color:magenta;
|
||||
.t_magenta {
|
||||
color: magenta;
|
||||
}
|
||||
|
||||
.t_cyan{
|
||||
color:cyan;
|
||||
.t_cyan {
|
||||
color: cyan;
|
||||
}
|
||||
|
||||
.t_limegreen{
|
||||
color:limegreen;
|
||||
.t_limegreen {
|
||||
color: limegreen;
|
||||
}
|
||||
|
||||
.t_skyblue{
|
||||
color:skyblue;
|
||||
.t_skyblue {
|
||||
color: skyblue;
|
||||
}
|
||||
|
||||
.t_orangered{
|
||||
color:orangered;
|
||||
.t_orangered {
|
||||
color: orangered;
|
||||
}
|
||||
|
||||
.t_yellow{
|
||||
color:yellow;
|
||||
.t_yellow {
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
.t_white{
|
||||
color:white;
|
||||
.t_white {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.float_left{
|
||||
float:left;
|
||||
.float_left {
|
||||
float: left;
|
||||
}
|
||||
|
||||
.tooltip{
|
||||
font-size:12px;
|
||||
.tooltip {
|
||||
font-size: 12px;
|
||||
font-family: '맑은 고딕';
|
||||
}
|
||||
|
||||
.tooltip_copyable_info .tooltiptext{
|
||||
.tooltip_copyable_info .tooltiptext {
|
||||
display: inline;
|
||||
color: rgba(0,0,0,0);
|
||||
color: rgba(0, 0, 0, 0);
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
@@ -202,67 +220,69 @@ div.bar_out div.bar_in{
|
||||
display: none;
|
||||
}
|
||||
|
||||
.hidden_but_copyable{
|
||||
color: rgba(0,0,0,0);
|
||||
.hidden_but_copyable {
|
||||
color: rgba(0, 0, 0, 0);
|
||||
font-size: 0;
|
||||
}
|
||||
|
||||
.btn-group-xs > .btn, .btn-xs {
|
||||
padding : .25rem .4rem;
|
||||
font-size : .875rem;
|
||||
line-height : .5;
|
||||
border-radius : .2rem;
|
||||
.btn-group-xs>.btn,
|
||||
.btn-xs {
|
||||
padding: .25rem .4rem;
|
||||
font-size: .875rem;
|
||||
line-height: .5;
|
||||
border-radius: .2rem;
|
||||
}
|
||||
|
||||
.edit_form.viewer{
|
||||
max-height:200px;
|
||||
overflow-y:auto;
|
||||
.edit_form.viewer {
|
||||
max-height: 200px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.trumbowyg-box{
|
||||
margin:0;
|
||||
border-left:none;
|
||||
border-right:none;
|
||||
.trumbowyg-box {
|
||||
margin: 0;
|
||||
border-left: none;
|
||||
border-right: none;
|
||||
}
|
||||
|
||||
.edit_form.trumbowyg-editor{
|
||||
margin:0;
|
||||
padding:0;
|
||||
.edit_form.trumbowyg-editor {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.commandBasic{
|
||||
background-color:black;
|
||||
color:white;
|
||||
.commandBasic {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.compensatePositive{
|
||||
color:skyblue;
|
||||
.compensatePositive {
|
||||
color: skyblue;
|
||||
}
|
||||
|
||||
.compensateNegative{
|
||||
color:orange;
|
||||
.compensateNegative {
|
||||
color: orange;
|
||||
}
|
||||
|
||||
.compensateNeutral{
|
||||
color:white;
|
||||
.compensateNeutral {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.commandBasic.commandImpossible{
|
||||
background-color:red;
|
||||
color:white;
|
||||
.commandBasic.commandImpossible {
|
||||
background-color: red;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.select2-selection--single.simple-select2-align-center .select2-selection__rendered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.select2-dropdown.simple-select2-align-center li.select2-results__option{
|
||||
.select2-dropdown.simple-select2-align-center li.select2-results__option {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.select2-container--bootstrap4 .select2-selection--single.text-secondary .select2-selection__rendered{
|
||||
color:white;
|
||||
.select2-container--bootstrap4 .select2-selection--single.text-secondary .select2-selection__rendered {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.select2-container--bootstrap4 .text-secondary .select2-results__option[aria-selected=false]{
|
||||
color:white;
|
||||
}
|
||||
.select2-container--bootstrap4 .text-secondary .select2-results__option[aria-selected=false] {
|
||||
color: white;
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
.section_bar{
|
||||
text-align:center;
|
||||
border:0.5px solid #aaa;
|
||||
padding-right:0;
|
||||
padding-left:0;
|
||||
}
|
||||
|
||||
.sub_bar{
|
||||
text-align:center;
|
||||
border:0.5px solid #aaa;
|
||||
margin-left:-5px;
|
||||
margin-right:-5px;
|
||||
}
|
||||
|
||||
.reset_btn{
|
||||
width:15ch;
|
||||
}
|
||||
|
||||
.submit_btn{
|
||||
margin-left:1em;
|
||||
width:15ch;
|
||||
}
|
||||
|
||||
.control_bar{
|
||||
margin-top:8pt;
|
||||
text-align:right;
|
||||
}
|
||||
|
||||
.col-form-label{
|
||||
text-align:right;
|
||||
padding-right:2ch;
|
||||
}
|
||||
|
||||
.form_list{
|
||||
padding:8pt;
|
||||
}
|
||||
|
||||
.half_section_left{
|
||||
padding-right:0;
|
||||
border-right:0.5px solid #aaa;
|
||||
}
|
||||
.half_section_right{
|
||||
padding-left:0;
|
||||
|
||||
}
|
||||
|
||||
.popover{
|
||||
max-width:100%;
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
@charset "UTF-8";
|
||||
.container {
|
||||
width: 1000px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.card_holder {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.general_card {
|
||||
width: 125px;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.general_card h4 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.general_card p {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.general_card .select_btn {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.general_card label {
|
||||
display: block;
|
||||
padding-left: 15px;
|
||||
text-indent: -15px;
|
||||
}
|
||||
|
||||
.general_card input {
|
||||
width: 13px;
|
||||
height: 13px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
vertical-align: bottom;
|
||||
position: relative;
|
||||
top: -1px;
|
||||
*overflow: hidden;
|
||||
}
|
||||
|
||||
#outdate_token {
|
||||
color: red;
|
||||
display: none;
|
||||
}
|
||||
|
||||
#left_pad button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.custom_picture {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.custom_personality {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.custom_stat {
|
||||
display: none;
|
||||
}
|
||||
@@ -1,8 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
class DB{
|
||||
//https://hub.packtpub.com/eloquent-without-laravel/
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
class DB
|
||||
{
|
||||
private static $uDB = null;
|
||||
private static ?Capsule $uIlluminate = null;
|
||||
|
||||
private static $host = '_tK_host_';
|
||||
private static $user = '_tK_user_';
|
||||
@@ -10,11 +18,36 @@ class DB{
|
||||
private static $dbName = '_tK_dbName_';
|
||||
private static $port = _tK_port_;
|
||||
private static $encoding = 'utf8mb4';
|
||||
private static $collation = 'utf8mb4_general_ci';
|
||||
|
||||
private static $prefix = '_tK_prefix_';
|
||||
|
||||
private function __construct(){
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function illuminate(): Capsule
|
||||
{
|
||||
if(self::$uIlluminate !== null){
|
||||
return self::$uIlluminate;
|
||||
}
|
||||
$capsule = new Capsule;
|
||||
|
||||
$capsule->addConnection([
|
||||
'driver' => 'mysql',
|
||||
'host' => self::$host,
|
||||
'database' => self::$dbName,
|
||||
'username' => self::$user,
|
||||
'password' => self::$password,
|
||||
'charset' => self::$encoding,
|
||||
'collation' => self::$collation,
|
||||
]);
|
||||
|
||||
$capsule->setEventDispatcher(new Dispatcher(new Container));
|
||||
$capsule->setAsGlobal();
|
||||
$capsule->bootEloquent();
|
||||
self::$uIlluminate = $capsule;
|
||||
return $capsule;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,12 +56,14 @@ class DB{
|
||||
* @return \MeekroDB
|
||||
* @suppress PhanTypeMismatchProperty
|
||||
*/
|
||||
public static function db(){
|
||||
if(self::$uDB === null){
|
||||
self::$uDB = new \MeekroDB(self::$host,self::$user,self::$password,self::$dbName,self::$port,self::$encoding);
|
||||
public static function db()
|
||||
{
|
||||
if (self::$uDB === null) {
|
||||
self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding);
|
||||
self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
|
||||
|
||||
self::$uDB->error_handler= function(){};
|
||||
self::$uDB->error_handler = function () {
|
||||
};
|
||||
self::$uDB->throw_exception_on_error = true;
|
||||
self::$uDB->throw_exception_on_nonsql_error = true;
|
||||
}
|
||||
@@ -39,4 +74,4 @@ class DB{
|
||||
{
|
||||
return self::$prefix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
class VersionGit extends VersionGitDynamic {
|
||||
}
|
||||
//{"version":"dynamic","hash":"dynamic"}
|
||||
@@ -2,8 +2,15 @@
|
||||
namespace sammo;
|
||||
|
||||
class VersionGit{
|
||||
public static $version = '_tK_verionGit_';
|
||||
static function getVersion()
|
||||
{
|
||||
return '_tK_verionGit_';
|
||||
}
|
||||
|
||||
static function getHash(){
|
||||
return '_tK_hash_';
|
||||
}
|
||||
|
||||
private function __construct(){}
|
||||
}
|
||||
//{"version":"_tK_verionGit_"}
|
||||
//{"version":"_tK_verionGit_","hash":"_tK_hash_"}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<div class="buttonPlate bg1">
|
||||
<div>
|
||||
<a href="a_status.php" target="_blank"><button class="toolbarButton">세력도</button></a>
|
||||
<a href="a_kingdomList.php" target="_blank"><button class="toolbarButton">세력일람</button></a>
|
||||
<a href="a_genList.php" target="_blank"><button class="toolbarButton">장수일람</button></a>
|
||||
<a href="a_bestGeneral.php" target="_blank"><button class="toolbarButton">명장일람</button></a>
|
||||
<a href="a_history.php" target="_blank"><button class="toolbarButton">연감</button></a>
|
||||
<a href="a_hallOfFame.php" target="_blank"><button class="toolbarButton">명예의전당</button></a>
|
||||
<a href="a_emperior.php" target="_blank"><button class="toolbarButton">왕조일람</button></a>
|
||||
<a href="a_traffic.php" target="_blank"><button class="toolbarButton">접속량정보</button></a>
|
||||
<a href="a_status.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력도</button></a>
|
||||
<a href="a_kingdomList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력일람</button></a>
|
||||
<a href="a_genList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">장수일람</button></a>
|
||||
<a href="a_bestGeneral.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명장일람</button></a>
|
||||
<a href="a_history.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">연감</button></a>
|
||||
<a href="a_hallOfFame.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명예의전당</button></a>
|
||||
<a href="a_emperior.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">왕조일람</button></a>
|
||||
<a href="a_traffic.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">접속량정보</button></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/bbs/board" target="_blank"><button class="toolbarButton2">삼모게시판</button></a>
|
||||
<a href="/bbs/tip" target="_blank"><button class="toolbarButton">팁/강좌</button></a>
|
||||
<a href="/bbs/news" target="_blank"><button class="toolbarButton">삼국 일보</button></a>
|
||||
<a href="/bbs/history2" target="_blank"><button class="toolbarButton">개인 열전</button></a>
|
||||
<a href="/bbs/history3" target="_blank"><button class="toolbarButton">국가 열전</button></a>
|
||||
<a href="/bbs/patch" target="_blank"><button class="toolbarButton">패치 내역</button></a>
|
||||
<a href="../i_other/help.php" target="_blank"><button class="toolbarButton">튜토리얼</button></a>
|
||||
<a href="<?=$site?>" target="_blank"><button class="toolbarButton"><?=$call?></button></a>
|
||||
<a href="/bbs/board" target="_blank"><button type="button" class="toolbarButton2">삼모게시판</button></a>
|
||||
<a href="/bbs/tip" target="_blank"><button type="button" class="toolbarButton">팁/강좌</button></a>
|
||||
<a href="/bbs/news" target="_blank"><button type="button" class="toolbarButton">삼국 일보</button></a>
|
||||
<a href="/bbs/history2" target="_blank"><button type="button" class="toolbarButton">개인 열전</button></a>
|
||||
<a href="/bbs/history3" target="_blank"><button type="button" class="toolbarButton">국가 열전</button></a>
|
||||
<a href="/bbs/patch" target="_blank"><button type="button" class="toolbarButton">패치 내역</button></a>
|
||||
<a href="battle_simulator.php" target="_blank"><button type="button" class="toolbarButton">전투 시뮬레이터</button></a>
|
||||
<a href="<?=$site?>" target="_blank" class="open-window"><button type="button" class="toolbarButton"><?=$call?></button></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+2445
-2112
File diff suppressed because it is too large
Load Diff
+447
-447
@@ -1,448 +1,448 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Command\GeneralCommand;
|
||||
use sammo\Command\NationCommand;
|
||||
|
||||
function getGeneralTurnBrief(General $generalObj, array $turnList) {
|
||||
$result = [];
|
||||
|
||||
foreach($turnList as $turnIdx => [$action, $arg]){
|
||||
$commandObj = buildGeneralCommandClass($action, $generalObj, [], $arg);
|
||||
$turnText = $commandObj->getBrief();
|
||||
$result[$turnIdx] = $turnText;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function getNationTurnBrief(General $generalObj, array $turnList) {
|
||||
$result = [];
|
||||
|
||||
$tmpTurn = new LastTurn();
|
||||
foreach($turnList as $turnIdx => [$action, $arg]){
|
||||
$commandObj = buildNationCommandClass($action, $generalObj, [], $tmpTurn, $arg);
|
||||
$turnText = $commandObj->getBrief();
|
||||
$result[$turnIdx] = $turnText;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function pushGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pullGeneralCommand($generalID, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
|
||||
], 'general_id=%i ORDER BY turn_idx DESC', $generalID);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'general_id=%i AND turn_idx >= %i', $generalID, GameConst::$maxTurn);
|
||||
}
|
||||
|
||||
function pullGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pushGeneralCommand($generalID, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'general_id=%i AND turn_idx < %i', $generalID, $turnCnt);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
|
||||
], 'general_id=%i ORDER BY turn_idx ASC', $generalID);
|
||||
}
|
||||
|
||||
function repeatGeneralCommand(int $generalId, int $turnCnt){
|
||||
if($turnCnt <= 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$reqTurn = $turnCnt;
|
||||
if($turnCnt * 2 > GameConst::$maxTurn){
|
||||
$reqTurn = GameConst::$maxTurn - $turnCnt;
|
||||
}
|
||||
|
||||
$turnList = $db->query('SELECT turn_idx, `action`, arg, brief FROM general_turn WHERE general_id=%i AND turn_idx < %i', $generalId, $reqTurn);
|
||||
foreach($turnList as $turnItem){
|
||||
$turnIdx = $turnItem['turn_idx'];
|
||||
$turnTarget = iterator_to_array(Util::range($turnIdx+$turnCnt, GameConst::$maxTurn, $turnCnt));
|
||||
|
||||
$db->update('general_turn', [
|
||||
'action'=>$turnItem['action'],
|
||||
'arg'=>$turnItem['arg'],
|
||||
'brief'=>$turnItem['brief']
|
||||
], 'general_id=%i AND turn_idx IN %li', $generalId, $turnTarget);
|
||||
}
|
||||
}
|
||||
|
||||
function pushNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
if($nationID == 0){
|
||||
return;
|
||||
}
|
||||
if($officerLevel < 5){
|
||||
return;
|
||||
}
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pullNationCommand($nationID, $officerLevel, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxChiefTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
|
||||
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx DESC', $nationID, $officerLevel);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxChiefTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'nation_id=%i AND officer_level=%i AND turn_idx >= %i ORDER BY turn_idx ASC', $nationID, $officerLevel, GameConst::$maxChiefTurn);
|
||||
}
|
||||
|
||||
function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
if($nationID == 0){
|
||||
return;
|
||||
}
|
||||
if($officerLevel < 5){
|
||||
return;
|
||||
}
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pushNationCommand($nationID, $officerLevel, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxChiefTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxChiefTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식',
|
||||
], 'nation_id=%i AND officer_level=%i AND turn_idx < %i', $nationID, $officerLevel, $turnCnt);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
|
||||
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx ASC', $nationID, $officerLevel);
|
||||
}
|
||||
|
||||
function _setGeneralCommand(GeneralCommand $command, array $turnList):void {
|
||||
if(!$turnList){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$generalID = $command->getGeneral()->getID();
|
||||
$commandName = $command->getRawClassName();
|
||||
$arg = $command->getArg();
|
||||
$brief = $command->getBrief();
|
||||
|
||||
$db->update('general_turn', [
|
||||
'action'=>$commandName,
|
||||
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT),
|
||||
'brief'=>$brief
|
||||
], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList);
|
||||
}
|
||||
|
||||
function _setNationCommand(NationCommand $command, array $turnList):void {
|
||||
if(!$turnList){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$nationID = $command->getNationID();
|
||||
$officerLevel = $command->getOfficerLevel();
|
||||
$commandName = $command->getRawClassName();
|
||||
$arg = $command->getArg();
|
||||
$brief = $command->getBrief();
|
||||
|
||||
$db->update('nation_turn', [
|
||||
'action'=>$commandName,
|
||||
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT),
|
||||
'brief'=>$brief
|
||||
], 'nation_id = %i AND officer_level = %i AND turn_idx IN %li', $nationID, $officerLevel, $turnList);
|
||||
}
|
||||
|
||||
function sanitizeArg(?array $args):?array{
|
||||
if($args === null){
|
||||
return $args;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach($args as $key=>$value){
|
||||
if(is_array($value)){
|
||||
$result[$key] = sanitizeArg($value);
|
||||
}
|
||||
else if(is_string($value)){
|
||||
$result[$key] = StringUtil::neutralize(StringUtil::removeSpecialCharacter($value));
|
||||
}
|
||||
else{
|
||||
$result[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function checkCommandArg(?array $arg):?string{
|
||||
if($arg === null){
|
||||
return null;
|
||||
}
|
||||
$defaultCheck = [
|
||||
/*'string'=>[
|
||||
'nationName', 'optionText', 'itemType', 'nationType'
|
||||
],*/
|
||||
'integer'=>[
|
||||
'crewType', 'destGeneralID', 'destCityID', 'destNationID',
|
||||
'amount', 'colorType',
|
||||
'srcArmType', 'destArmType', //숙련전환 전용
|
||||
],
|
||||
'boolean'=>[
|
||||
'isGold', 'buyRice',
|
||||
],
|
||||
'between'=>[
|
||||
['month', [1, 12]]
|
||||
],
|
||||
'min'=>[
|
||||
['year', 0],
|
||||
['destGeneralID', 1],
|
||||
['destCityID', 1],
|
||||
['destNationID', 1],
|
||||
['amount', 1],
|
||||
['crewType', 0]
|
||||
],
|
||||
'integerArray'=>[
|
||||
'destNationIDList', 'destGeneralIDList', 'amountList'
|
||||
],
|
||||
'stringWidthBetween'=>[
|
||||
['nationName', 1, 18]
|
||||
]
|
||||
];
|
||||
$v = new Validator($arg);
|
||||
$v->rules($defaultCheck);
|
||||
if (!$v->validate()){
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setGeneralCommand(int $generalID, array $rawTurnList, string $command, ?array $arg = null):array{
|
||||
|
||||
$turnList = [];
|
||||
foreach($rawTurnList as $turnIdx){
|
||||
if(!is_int($turnIdx) || $turnIdx < -3 || $turnIdx >= GameConst::$maxTurn){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx,
|
||||
'test'=>'turnIdx',
|
||||
'target'=>$turnIdx,
|
||||
];
|
||||
}
|
||||
if($turnIdx >= 0){
|
||||
$turnList[$turnIdx] = true;
|
||||
}
|
||||
else if($turnIdx == -1){
|
||||
//홀수
|
||||
foreach(Util::range(1, GameConst::$maxTurn, 2) as $subIdx){
|
||||
$turnList[$subIdx] = true;
|
||||
}
|
||||
}
|
||||
else if($turnIdx == -2){
|
||||
//짝수
|
||||
foreach(Util::range(0, GameConst::$maxTurn, 2) as $subIdx){
|
||||
$turnList[$subIdx] = true;
|
||||
}
|
||||
}
|
||||
else if($turnIdx == -3){
|
||||
//모두
|
||||
foreach(Util::range(GameConst::$maxTurn) as $subIdx){
|
||||
$turnList[$subIdx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$turnList = array_keys($turnList);
|
||||
|
||||
$arg = sanitizeArg($arg);
|
||||
$argBasicTestResult = checkCommandArg($arg);
|
||||
if($argBasicTestResult !== null){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'턴이 입력되지 않았습니다.',
|
||||
'test'=>'checkCommandArg',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getAll();
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
try{
|
||||
$commandObj = buildGeneralCommandClass($command, $general, $env, $arg);
|
||||
}
|
||||
catch (\InvalidArgumentException $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
catch (\Exception $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getCode().$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->isArgValid()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 argument',
|
||||
'test'=>'isArgValid',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->hasPermissionToReserve()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
|
||||
'test'=>'hasPermissionToReserve',
|
||||
'target'=>'command'
|
||||
];
|
||||
}
|
||||
|
||||
_setGeneralCommand($commandObj, $turnList);
|
||||
return [
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
];
|
||||
}
|
||||
|
||||
function setNationCommand(int $generalID, array $turnList, string $command, ?array $arg = null):array{
|
||||
$turnList = array_unique($turnList);
|
||||
foreach($turnList as $turnIdx){
|
||||
if(!is_int($turnIdx) || $turnIdx < 0 || $turnIdx >= GameConst::$maxChiefTurn){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx,
|
||||
'test'=>'turnIdx',
|
||||
'target'=>$turnIdx,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$arg = sanitizeArg($arg);
|
||||
$argBasicTestResult = checkCommandArg($arg);
|
||||
if($argBasicTestResult !== null){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'턴이 입력되지 않았습니다.',
|
||||
'test'=>'checkCommandArg',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getAll();
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
if($general->getVar('officer_level') < 5){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'수뇌가 아닙니다'
|
||||
];
|
||||
}
|
||||
|
||||
try{
|
||||
$commandObj = buildNationCommandClass($command, $general, $env, $general->getLastTurn(), $arg);
|
||||
}
|
||||
catch (\InvalidArgumentException $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
catch (\Exception $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getCode().$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->isArgValid()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 argument',
|
||||
'test'=>'isArgValid',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->hasPermissionToReserve()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
|
||||
'test'=>'hasPermissionToReserve',
|
||||
'target'=>'command'
|
||||
];
|
||||
}
|
||||
|
||||
_setNationCommand($commandObj, $turnList);
|
||||
return [
|
||||
'result'=>true,
|
||||
'arg_test'=>true,
|
||||
'reason'=>'success'
|
||||
];
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Command\GeneralCommand;
|
||||
use sammo\Command\NationCommand;
|
||||
|
||||
function getGeneralTurnBrief(General $generalObj, array $turnList) {
|
||||
$result = [];
|
||||
|
||||
foreach($turnList as $turnIdx => [$action, $arg]){
|
||||
$commandObj = buildGeneralCommandClass($action, $generalObj, [], $arg);
|
||||
$turnText = $commandObj->getBrief();
|
||||
$result[$turnIdx] = $turnText;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function getNationTurnBrief(General $generalObj, array $turnList) {
|
||||
$result = [];
|
||||
|
||||
$tmpTurn = new LastTurn();
|
||||
foreach($turnList as $turnIdx => [$action, $arg]){
|
||||
$commandObj = buildNationCommandClass($action, $generalObj, [], $tmpTurn, $arg);
|
||||
$turnText = $commandObj->getBrief();
|
||||
$result[$turnIdx] = $turnText;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function pushGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pullGeneralCommand($generalID, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
|
||||
], 'general_id=%i ORDER BY turn_idx DESC', $generalID);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'general_id=%i AND turn_idx >= %i', $generalID, GameConst::$maxTurn);
|
||||
}
|
||||
|
||||
function pullGeneralCommand(int $generalID, int $turnCnt=1){
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pushGeneralCommand($generalID, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'general_id=%i AND turn_idx < %i', $generalID, $turnCnt);
|
||||
$db->update('general_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
|
||||
], 'general_id=%i ORDER BY turn_idx ASC', $generalID);
|
||||
}
|
||||
|
||||
function repeatGeneralCommand(int $generalId, int $turnCnt){
|
||||
if($turnCnt <= 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$reqTurn = $turnCnt;
|
||||
if($turnCnt * 2 > GameConst::$maxTurn){
|
||||
$reqTurn = GameConst::$maxTurn - $turnCnt;
|
||||
}
|
||||
|
||||
$turnList = $db->query('SELECT turn_idx, `action`, arg, brief FROM general_turn WHERE general_id=%i AND turn_idx < %i', $generalId, $reqTurn);
|
||||
foreach($turnList as $turnItem){
|
||||
$turnIdx = $turnItem['turn_idx'];
|
||||
$turnTarget = iterator_to_array(Util::range($turnIdx+$turnCnt, GameConst::$maxTurn, $turnCnt));
|
||||
|
||||
$db->update('general_turn', [
|
||||
'action'=>$turnItem['action'],
|
||||
'arg'=>$turnItem['arg'],
|
||||
'brief'=>$turnItem['brief']
|
||||
], 'general_id=%i AND turn_idx IN %li', $generalId, $turnTarget);
|
||||
}
|
||||
}
|
||||
|
||||
function pushNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
if($nationID == 0){
|
||||
return;
|
||||
}
|
||||
if($officerLevel < 5){
|
||||
return;
|
||||
}
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pullNationCommand($nationID, $officerLevel, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxChiefTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', $turnCnt)
|
||||
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx DESC', $nationID, $officerLevel);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', GameConst::$maxChiefTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식'
|
||||
], 'nation_id=%i AND officer_level=%i AND turn_idx >= %i ORDER BY turn_idx ASC', $nationID, $officerLevel, GameConst::$maxChiefTurn);
|
||||
}
|
||||
|
||||
function pullNationCommand(int $nationID, int $officerLevel, int $turnCnt=1){
|
||||
if($nationID == 0){
|
||||
return;
|
||||
}
|
||||
if($officerLevel < 5){
|
||||
return;
|
||||
}
|
||||
if($turnCnt == 0){
|
||||
return;
|
||||
}
|
||||
if($turnCnt < 0){
|
||||
pushNationCommand($nationID, $officerLevel, -$turnCnt);
|
||||
return;
|
||||
}
|
||||
if($turnCnt >= GameConst::$maxChiefTurn){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx + %i', GameConst::$maxChiefTurn),
|
||||
'action'=>'휴식',
|
||||
'arg'=>'{}',
|
||||
'brief'=>'휴식',
|
||||
], 'nation_id=%i AND officer_level=%i AND turn_idx < %i', $nationID, $officerLevel, $turnCnt);
|
||||
$db->update('nation_turn', [
|
||||
'turn_idx'=>$db->sqleval('turn_idx - %i', $turnCnt)
|
||||
], 'nation_id=%i AND officer_level=%i ORDER BY turn_idx ASC', $nationID, $officerLevel);
|
||||
}
|
||||
|
||||
function _setGeneralCommand(GeneralCommand $command, array $turnList):void {
|
||||
if(!$turnList){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$generalID = $command->getGeneral()->getID();
|
||||
$commandName = $command->getRawClassName();
|
||||
$arg = $command->getArg();
|
||||
$brief = $command->getBrief();
|
||||
|
||||
$db->update('general_turn', [
|
||||
'action'=>$commandName,
|
||||
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT),
|
||||
'brief'=>$brief
|
||||
], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList);
|
||||
}
|
||||
|
||||
function _setNationCommand(NationCommand $command, array $turnList):void {
|
||||
if(!$turnList){
|
||||
return;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$nationID = $command->getNationID();
|
||||
$officerLevel = $command->getOfficerLevel();
|
||||
$commandName = $command->getRawClassName();
|
||||
$arg = $command->getArg();
|
||||
$brief = $command->getBrief();
|
||||
|
||||
$db->update('nation_turn', [
|
||||
'action'=>$commandName,
|
||||
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT),
|
||||
'brief'=>$brief
|
||||
], 'nation_id = %i AND officer_level = %i AND turn_idx IN %li', $nationID, $officerLevel, $turnList);
|
||||
}
|
||||
|
||||
function sanitizeArg(?array $args):?array{
|
||||
if($args === null){
|
||||
return $args;
|
||||
}
|
||||
|
||||
$result = [];
|
||||
foreach($args as $key=>$value){
|
||||
if(is_array($value)){
|
||||
$result[$key] = sanitizeArg($value);
|
||||
}
|
||||
else if(is_string($value)){
|
||||
$result[$key] = StringUtil::neutralize(StringUtil::removeSpecialCharacter($value));
|
||||
}
|
||||
else{
|
||||
$result[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function checkCommandArg(?array $arg):?string{
|
||||
if($arg === null){
|
||||
return null;
|
||||
}
|
||||
$defaultCheck = [
|
||||
/*'string'=>[
|
||||
'nationName', 'optionText', 'itemType', 'nationType', 'commandType',
|
||||
],*/
|
||||
'integer'=>[
|
||||
'crewType', 'destGeneralID', 'destCityID', 'destNationID',
|
||||
'amount', 'colorType',
|
||||
'srcArmType', 'destArmType', //숙련전환 전용
|
||||
],
|
||||
'boolean'=>[
|
||||
'isGold', 'buyRice',
|
||||
],
|
||||
'between'=>[
|
||||
['month', [1, 12]]
|
||||
],
|
||||
'min'=>[
|
||||
['year', 0],
|
||||
['destGeneralID', 1],
|
||||
['destCityID', 1],
|
||||
['destNationID', 1],
|
||||
['amount', 1],
|
||||
['crewType', 0]
|
||||
],
|
||||
'integerArray'=>[
|
||||
'destNationIDList', 'destGeneralIDList', 'amountList'
|
||||
],
|
||||
'stringWidthBetween'=>[
|
||||
['nationName', 1, 18]
|
||||
]
|
||||
];
|
||||
$v = new Validator($arg);
|
||||
$v->rules($defaultCheck);
|
||||
if (!$v->validate()){
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function setGeneralCommand(int $generalID, array $rawTurnList, string $command, ?array $arg = null):array{
|
||||
|
||||
$turnList = [];
|
||||
foreach($rawTurnList as $turnIdx){
|
||||
if(!is_int($turnIdx) || $turnIdx < -3 || $turnIdx >= GameConst::$maxTurn){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx,
|
||||
'test'=>'turnIdx',
|
||||
'target'=>$turnIdx,
|
||||
];
|
||||
}
|
||||
if($turnIdx >= 0){
|
||||
$turnList[$turnIdx] = true;
|
||||
}
|
||||
else if($turnIdx == -1){
|
||||
//홀수, 0부터 맞다.
|
||||
foreach(Util::range(0, GameConst::$maxTurn, 2) as $subIdx){
|
||||
$turnList[$subIdx] = true;
|
||||
}
|
||||
}
|
||||
else if($turnIdx == -2){
|
||||
//짝수, 1부터 맞다.
|
||||
foreach(Util::range(1, GameConst::$maxTurn, 2) as $subIdx){
|
||||
$turnList[$subIdx] = true;
|
||||
}
|
||||
}
|
||||
else if($turnIdx == -3){
|
||||
//모두
|
||||
foreach(Util::range(GameConst::$maxTurn) as $subIdx){
|
||||
$turnList[$subIdx] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
$turnList = array_keys($turnList);
|
||||
|
||||
$arg = sanitizeArg($arg);
|
||||
$argBasicTestResult = checkCommandArg($arg);
|
||||
if($argBasicTestResult !== null){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'턴이 입력되지 않았습니다.',
|
||||
'test'=>'checkCommandArg',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getAll();
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
try{
|
||||
$commandObj = buildGeneralCommandClass($command, $general, $env, $arg);
|
||||
}
|
||||
catch (\InvalidArgumentException $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
catch (\Exception $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getCode().$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->isArgValid()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 argument',
|
||||
'test'=>'isArgValid',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->hasPermissionToReserve()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
|
||||
'test'=>'hasPermissionToReserve',
|
||||
'target'=>'command'
|
||||
];
|
||||
}
|
||||
|
||||
_setGeneralCommand($commandObj, $turnList);
|
||||
return [
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
];
|
||||
}
|
||||
|
||||
function setNationCommand(int $generalID, array $turnList, string $command, ?array $arg = null):array{
|
||||
$turnList = array_unique($turnList);
|
||||
foreach($turnList as $turnIdx){
|
||||
if(!is_int($turnIdx) || $turnIdx < 0 || $turnIdx >= GameConst::$maxChiefTurn){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 턴이 아닙니다. : '.$turnIdx,
|
||||
'test'=>'turnIdx',
|
||||
'target'=>$turnIdx,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$arg = sanitizeArg($arg);
|
||||
$argBasicTestResult = checkCommandArg($arg);
|
||||
if($argBasicTestResult !== null){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'턴이 입력되지 않았습니다.',
|
||||
'test'=>'checkCommandArg',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getAll();
|
||||
$general = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
if($general->getVar('officer_level') < 5){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'수뇌가 아닙니다'
|
||||
];
|
||||
}
|
||||
|
||||
try{
|
||||
$commandObj = buildNationCommandClass($command, $general, $env, $general->getLastTurn(), $arg);
|
||||
}
|
||||
catch (\InvalidArgumentException $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
catch (\Exception $e){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>$e->getCode().$e->getMessage(),
|
||||
'test'=>'build',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->isArgValid()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 argument',
|
||||
'test'=>'isArgValid',
|
||||
'target'=>'arg'
|
||||
];
|
||||
}
|
||||
|
||||
if(!$commandObj->hasPermissionToReserve()){
|
||||
return [
|
||||
'result'=>false,
|
||||
'reason'=>'예약 불가능한 커맨드 :'.$commandObj->testPermissionToReserve(),
|
||||
'test'=>'hasPermissionToReserve',
|
||||
'target'=>'command'
|
||||
];
|
||||
}
|
||||
|
||||
_setNationCommand($commandObj, $turnList);
|
||||
return [
|
||||
'result'=>true,
|
||||
'arg_test'=>true,
|
||||
'reason'=>'success'
|
||||
];
|
||||
}
|
||||
+34
-10
@@ -1,4 +1,4 @@
|
||||
<?php
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
@@ -6,7 +6,7 @@ use sammo\Command\BaseCommand;
|
||||
|
||||
/**
|
||||
* Value Converter
|
||||
*
|
||||
*
|
||||
* Side effect 없이 값의 변환만을 수행하는 함수들의 모음.
|
||||
* (단, autoload, 정적 변수 초기화는 허용)
|
||||
*/
|
||||
@@ -175,7 +175,7 @@ function buildNationTypeClass(?string $type):BaseNation{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getNationTypeClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -241,7 +241,7 @@ function buildItemClass(?string $type):BaseItem{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getItemClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -276,7 +276,7 @@ function buildGeneralSpecialDomesticClass(?string $type):BaseSpecial{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getGeneralSpecialDomesticClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -311,7 +311,7 @@ function buildGeneralSpecialWarClass(?string $type):BaseSpecial{
|
||||
return $cache[$type];
|
||||
}
|
||||
$class = getGeneralSpecialWarClass($type);
|
||||
|
||||
|
||||
$obj = new $class();
|
||||
$cache[$type]= $obj;
|
||||
return $obj;
|
||||
@@ -378,6 +378,30 @@ function buildWarUnitTriggerClass(?string $type, WarUnit $unit, ?array $args = n
|
||||
return $class->newInstanceArgs(array_merge([$unit], $args));
|
||||
}
|
||||
|
||||
function getGeneralPoolClass(string $type){
|
||||
static $basePath = __NAMESPACE__.'\\GeneralPool\\';
|
||||
$classPath = ($basePath.$type);
|
||||
|
||||
if(class_exists($classPath)){
|
||||
return $classPath;
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException("{$type}은 GeneralPool이 아님");
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MeekroDB $db
|
||||
* @param int $owner
|
||||
* @param int $pickCnt
|
||||
* @param null|string $prefix
|
||||
* @return AbsGeneralPool[]
|
||||
*/
|
||||
function pickGeneralFromPool(\MeekroDB $db, int $owner, int $pickCnt, ?string $prefix=null):array{
|
||||
/** @var AbsGeneralPool */
|
||||
$class = getGeneralPoolClass(GameConst::$targetGeneralPool);
|
||||
return $class::pickGeneralFromPool($db, $owner, $pickCnt, $prefix);
|
||||
}
|
||||
|
||||
function countPureGeneralFromRawList(?array $rawGeneralList=null):int{
|
||||
if(!$rawGeneralList){
|
||||
return 0;
|
||||
@@ -514,8 +538,8 @@ function getExpLevel($experience) {
|
||||
|
||||
function getDedLevel($dedication) {
|
||||
$level = Util::valueFit(
|
||||
ceil(sqrt($dedication) / 10),
|
||||
0,
|
||||
ceil(sqrt($dedication) / 10),
|
||||
0,
|
||||
GameConst::$maxDedLevel
|
||||
);
|
||||
|
||||
@@ -548,7 +572,7 @@ function getCost(int $armtype) : int {
|
||||
function getTechLevel($tech):int{
|
||||
return Util::valueFit(
|
||||
floor($tech / 1000),
|
||||
0,
|
||||
0,
|
||||
GameConst::$maxTechLevel
|
||||
);
|
||||
}
|
||||
@@ -559,7 +583,7 @@ function TechLimit($startYear, $year, $tech) : bool {
|
||||
|
||||
$relMaxTech = Util::valueFit(
|
||||
floor($relYear / 5) + 1,
|
||||
1,
|
||||
1,
|
||||
GameConst::$maxTechLevel
|
||||
);
|
||||
|
||||
|
||||
+1219
-1138
@@ -1,1138 +1,1219 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* 게임 룰에 해당하는 함수 모음
|
||||
*/
|
||||
|
||||
function getNationLevelList(): array
|
||||
{
|
||||
$table = [
|
||||
0 => ['방랑군', 2, 0],
|
||||
1 => ['호족', 2, 1],
|
||||
2 => ['군벌', 4, 2],
|
||||
3 => ['주자사', 4, 5],
|
||||
4 => ['주목', 6, 8],
|
||||
5 => ['공', 6, 11],
|
||||
6 => ['왕', 8, 16],
|
||||
7 => ['황제', 8, 21],
|
||||
];
|
||||
return $table;
|
||||
}
|
||||
|
||||
function getCityLevelList(): array
|
||||
{
|
||||
return [
|
||||
1 => '수',
|
||||
2 => '진',
|
||||
3 => '관',
|
||||
4 => '이',
|
||||
5 => '소',
|
||||
6 => '중',
|
||||
7 => '대',
|
||||
8 => '특'
|
||||
];
|
||||
}
|
||||
|
||||
//한국가의 전체 전방 설정
|
||||
function SetNationFront($nationNo)
|
||||
{
|
||||
if (!$nationNo) {
|
||||
return;
|
||||
}
|
||||
// 도시소유 국가와 선포,교전중인 국가
|
||||
|
||||
$adj3 = [];
|
||||
$adj2 = [];
|
||||
$adj1 = [];
|
||||
|
||||
$db = DB::db();
|
||||
foreach ($db->queryFirstColumn(
|
||||
'SELECT city FROM city JOIN diplomacy ON diplomacy.you = city.nation WHERE diplomacy.state = 0 AND me = %i',
|
||||
$nationNo
|
||||
) as $city) {
|
||||
foreach (CityConst::byID($city)->path as $adjKey => $adjVal) {
|
||||
$adj3[$adjKey] = $adjVal;
|
||||
}
|
||||
};
|
||||
foreach ($db->queryFirstColumn(
|
||||
'SELECT city FROM city JOIN diplomacy ON diplomacy.you = city.nation WHERE diplomacy.state = 1 AND diplomacy.term <= 5 AND me = %i',
|
||||
$nationNo
|
||||
) as $city) {
|
||||
foreach (CityConst::byID($city)->path as $adjKey => $adjVal) {
|
||||
$adj1[$adjKey] = $adjVal;
|
||||
}
|
||||
}
|
||||
if (!$adj3 && !$adj1) {
|
||||
//평시이면 공백지
|
||||
//NOTE: if, else일 경우 NPC는 전쟁시에는 공백지로 출병하지 않는다는 뜻이 된다.
|
||||
foreach ($db->queryFirstColumn('SELECT city from city where nation=0') as $city) {
|
||||
foreach (CityConst::byID($city)->path as $adjKey => $adjVal) {
|
||||
$adj2[$adjKey] = $adjVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$db->update('city', [
|
||||
'front' => 0
|
||||
], 'nation=%i', $nationNo);
|
||||
|
||||
if ($adj1) {
|
||||
$db->update('city', [
|
||||
'front' => 1,
|
||||
], 'nation=%i and city in %li', $nationNo, array_keys($adj1));
|
||||
}
|
||||
if ($adj2) {
|
||||
$db->update('city', [
|
||||
'front' => 2,
|
||||
], 'nation=%i and city in %li', $nationNo, array_keys($adj2));
|
||||
}
|
||||
if ($adj3) {
|
||||
$db->update('city', [
|
||||
'front' => 3,
|
||||
], 'nation=%i and city in %li', $nationNo, array_keys($adj3));
|
||||
}
|
||||
}
|
||||
|
||||
function checkSupply()
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$cities = [];
|
||||
foreach ($db->query('SELECT city, nation FROM city WHERE nation != 0') as $city) {
|
||||
$newCity = new \stdClass();
|
||||
$newCity->id = Util::toInt($city['city']);
|
||||
$newCity->nation = Util::toInt($city['nation']);
|
||||
$newCity->supply = false;
|
||||
|
||||
$cities[$newCity->id] = $newCity;
|
||||
}
|
||||
|
||||
$queue = new \SplQueue();
|
||||
foreach ($db->queryAllLists('SELECT capital, nation FROM nation WHERE `level` > 0') as list($capitalID, $nationID)) {
|
||||
if (!key_exists($capitalID, $cities)) {
|
||||
continue;
|
||||
}
|
||||
$city = $cities[$capitalID];
|
||||
if ($nationID != $city->nation) {
|
||||
continue;
|
||||
}
|
||||
$city->supply = true;
|
||||
$queue->enqueue($city);
|
||||
}
|
||||
|
||||
while (!$queue->isEmpty()) {
|
||||
$cityLink = $queue->dequeue();
|
||||
$city = CityConst::byID($cityLink->id);
|
||||
|
||||
foreach (array_keys($city->path) as $connCityID) {
|
||||
if (!key_exists($connCityID, $cities)) {
|
||||
continue;
|
||||
}
|
||||
$connCity = $cities[$connCityID];
|
||||
if ($connCity->nation != $cityLink->nation) {
|
||||
continue;
|
||||
}
|
||||
if ($connCity->supply) {
|
||||
continue;
|
||||
}
|
||||
$connCity->supply = true;
|
||||
$queue->enqueue($connCity);
|
||||
}
|
||||
}
|
||||
|
||||
$db->update('city', [
|
||||
'supply' => 1
|
||||
], 'nation=0');
|
||||
|
||||
$db->update('city', [
|
||||
'supply' => 0
|
||||
], 'nation!=0');
|
||||
|
||||
$supply = [];
|
||||
|
||||
foreach ($cities as $city) {
|
||||
if ($city->supply) {
|
||||
$supply[] = $city->id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($supply) {
|
||||
$db->update('city', [
|
||||
'supply' => 1
|
||||
], 'city IN %li', $supply);
|
||||
}
|
||||
}
|
||||
|
||||
function updateGeneralNumber(){
|
||||
$db = DB::db();
|
||||
foreach($db->queryAllLists('SELECT nation, count(*) FROM general WHERE npc != 5 GROUP BY nation') as [$nationID, $gennum]){
|
||||
if($nationID === 0){
|
||||
continue;
|
||||
}
|
||||
$db->update('nation', [
|
||||
'gennum'=>$gennum
|
||||
], 'nation=%i', $nationID);
|
||||
}
|
||||
refreshNationStaticInfo();
|
||||
}
|
||||
|
||||
function updateYearly()
|
||||
{
|
||||
//통계
|
||||
checkStatistic();
|
||||
}
|
||||
|
||||
//관직 변경 해제
|
||||
function updateQuaterly()
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
//천도 제한 해제, 관직 변경 제한 해제
|
||||
$db->update('nation', [
|
||||
'chief_set' => 0,
|
||||
], true);
|
||||
//관직 변경 제한 해제
|
||||
$db->update('city', [
|
||||
'officer_set' => 0,
|
||||
], true);
|
||||
}
|
||||
|
||||
// 벌점 감소와 건국제한-1 전턴제한-1 외교제한-1, 1달마다 실행, 병사 있는 장수의 군량 감소, 수입비율 조정
|
||||
function preUpdateMonthly()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
//연감 월결산
|
||||
$result = LogHistory();
|
||||
|
||||
if ($result == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$admin = $gameStor->getValues(['startyear', 'year', 'month']);
|
||||
$logger = new ActionLogger(0, 0, $admin['year'], $admin['month']);
|
||||
|
||||
//보급선 체크
|
||||
checkSupply();
|
||||
//미보급도시 10% 감소
|
||||
$db->update('city', [
|
||||
'pop' => $db->sqleval('pop * 0.9'),
|
||||
'trust' => $db->sqleval('trust * 0.9'),
|
||||
'agri' => $db->sqleval('agri * 0.9'),
|
||||
'comm' => $db->sqleval('comm * 0.9'),
|
||||
'secu' => $db->sqleval('secu * 0.9'),
|
||||
'def' => $db->sqleval('def * 0.9'),
|
||||
'wall' => $db->sqleval('wall * 0.9'),
|
||||
], 'supply = 0');
|
||||
//미보급도시 장수 병 훈 사 5%감소
|
||||
//NOTE: update inner join도 가능하지만, meekrodb 기준으로 깔끔하게.
|
||||
$unsuppliedCities = $db->query('SELECT city, nation, trust, name FROM city WHERE supply = 0');
|
||||
foreach (Util::arrayGroupBy($unsuppliedCities, 'nation') as $nationID => $cityList) {
|
||||
$cityIDList = Util::squeezeFromArray($cityList, 'city');
|
||||
$db->update('general', [
|
||||
'crew' => $db->sqleval('crew*0.95'),
|
||||
'atmos' => $db->sqleval('atmos*0.95'),
|
||||
'train' => $db->sqleval('train*0.95'),
|
||||
], 'city IN %li AND nation = %i', $cityIDList, $nationID);
|
||||
}
|
||||
|
||||
//민심30이하 공백지 처리
|
||||
$lostCities = [];
|
||||
foreach ($unsuppliedCities as $unsuppliedCity) {
|
||||
if ($unsuppliedCity['trust'] >= 30) {
|
||||
continue;
|
||||
}
|
||||
$lostCities[$unsuppliedCity['city']] = $unsuppliedCity;
|
||||
}
|
||||
|
||||
if ($lostCities) {
|
||||
foreach ($lostCities as $lostCity) {
|
||||
$josaYi = JosaUtil::pick($lostCity['name'], '이');
|
||||
$logger->pushGlobalHistoryLog("<R><b>【고립】</b></><G><b>{$lostCity['name']}</b></>{$josaYi} 보급이 끊겨 <R>미지배</> 도시가 되었습니다.");
|
||||
}
|
||||
$db->update('general', [
|
||||
'officer_level' => 1,
|
||||
'officer_city' => 0
|
||||
], 'officer_city IN %li', array_keys($lostCities));
|
||||
$db->update('city', [
|
||||
'nation' => 0,
|
||||
'officer_set' => 0,
|
||||
'conflict' => '{}',
|
||||
'term' => 0,
|
||||
'front' => 0
|
||||
], 'city IN %li', array_keys($lostCities));
|
||||
}
|
||||
|
||||
//접률감소, 건국제한-1
|
||||
$db->update('general', [
|
||||
'connect' => $db->sqleval('floor(connect*0.99)'),
|
||||
'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'),
|
||||
], true);
|
||||
//전략제한-1, 외교제한-1, 세율동기화
|
||||
$db->update('nation', [
|
||||
'strategic_cmd_limit' => $db->sqleval('greatest(0, strategic_cmd_limit - 1)'),
|
||||
'surlimit' => $db->sqleval('greatest(0, surlimit - 1)'),
|
||||
'rate_tmp' => $db->sqleval('rate')
|
||||
], true);
|
||||
|
||||
//도시훈사 180년 60, 220년 87, 240년 100
|
||||
$rate = Util::round(($admin['year'] - $admin['startyear']) / 1.5) + 60;
|
||||
if ($rate > 100) $rate = 100;
|
||||
|
||||
// 20 ~ 140원
|
||||
$develcost = ($admin['year'] - $admin['startyear'] + 10) * 2;
|
||||
$gameStor->city_rate = $rate;
|
||||
$gameStor->develcost = $develcost;
|
||||
|
||||
//매달 사망자 수입 결산
|
||||
processWarIncome();
|
||||
|
||||
//계략, 전쟁표시 해제
|
||||
$db->update('city', [
|
||||
'state' => $db->sqleval(<<<EOD
|
||||
(CASE
|
||||
WHEN state=31 THEN 0
|
||||
WHEN state=32 THEN 31
|
||||
WHEN state=33 THEN 0
|
||||
WHEN state=34 THEN 33
|
||||
WHEN state=41 THEN 0
|
||||
WHEN state=42 THEN 41
|
||||
WHEN state=43 THEN 42
|
||||
ELSE state END)
|
||||
EOD),
|
||||
'term' => $db->sqleval('greatest(0, term - 1)'),
|
||||
'conflict' => $db->sqleval('if(term = 0,%s,conflict)', '{}'),
|
||||
], true);
|
||||
|
||||
//첩보-1
|
||||
foreach ($db->queryAllLists("SELECT nation, spy FROM nation WHERE spy!='' AND spy!='{}'") as [$nationNo, $rawSpy]) {
|
||||
$spyInfo = Json::decode($rawSpy);
|
||||
|
||||
foreach ($spyInfo as $cityNo => $remainMonth) {
|
||||
if ($remainMonth <= 1) {
|
||||
unset($spyInfo[$cityNo]);
|
||||
} else {
|
||||
$spyInfo[$cityNo] -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
$db->update('nation', [
|
||||
'spy' => Json::encode($spyInfo, Json::EMPTY_ARRAY_IS_DICT)
|
||||
], 'nation=%i', $nationNo);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 외교 로그처리, 외교 상태 처리
|
||||
function postUpdateMonthly()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['startyear', 'year', 'month', 'scenario']);
|
||||
$globalLogger = new ActionLogger(0, 0, $admin['year'], $admin['month']);
|
||||
|
||||
//도시 수 측정
|
||||
$cityNations = [];
|
||||
foreach ($db->queryAllLists('SELECT city, name, nation FROM city') as [$cityID, $cityName, $cityNation]) {
|
||||
if (!key_exists($cityNation, $cityNations)) {
|
||||
$cityNations[$cityNation] = [];
|
||||
}
|
||||
$cityNations[$cityNation][] = $cityName;
|
||||
}
|
||||
|
||||
//각 국가 전월 장수수 대비 당월 장수수로 단합도 산정
|
||||
//각 국가 장수수를 구하고 국력 산정
|
||||
// $query = "select nation,gennum from nation where level>0";
|
||||
// 국력=
|
||||
// 자원(국가/장수의 금,쌀)
|
||||
// 기술력
|
||||
// 인구수*내정%
|
||||
// 장수능력
|
||||
// 접속률
|
||||
// 숙련도
|
||||
// 명성,공헌
|
||||
$nations = Util::convertArrayToDict($db->query('SELECT
|
||||
A.nation,
|
||||
A.gennum,
|
||||
round((
|
||||
round(((A.gold+A.rice)+(select sum(gold+rice) from general where nation=A.nation))/100)
|
||||
+A.tech
|
||||
+if(A.level=0,0,(
|
||||
select round(
|
||||
sum(pop)*sum(pop+agri+comm+secu+wall+def)/sum(pop_max+agri_max+comm_max+secu_max+wall_max+def_max)/100
|
||||
) from city where nation=A.nation and supply=1
|
||||
))
|
||||
+(select sum(leadership+strength+intel) from general where nation=A.nation)
|
||||
+(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation)
|
||||
+(select round(sum(experience+dedication)/100) from general where nation=A.nation)
|
||||
+(select round(avg(connect)) from general where nation=A.nation)
|
||||
)/10)
|
||||
as power,
|
||||
(select sum(crew) from general where nation=A.nation) as totalCrew
|
||||
from nation A
|
||||
group by A.nation'), 'nation');
|
||||
$maxPowerValues = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'max_power');
|
||||
|
||||
foreach ($nations as $nation) {
|
||||
$nationID = $nation['nation'];
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$genNum[$nationID] = $nation['gennum'];
|
||||
|
||||
$powerValues = $maxPowerValues[$nationID]??[];
|
||||
|
||||
//약간의 랜덤치 부여 (95% ~ 105%)
|
||||
|
||||
$nation['power'] = Util::round($nation['power'] * (rand() % 101 + 950) / 1000);
|
||||
$powerValues['maxPower'] = max($powerValues['maxPower'] ?? 0, $nation['power']);
|
||||
$powerValues['maxCrew'] = max($powerValues['maxCrew'] ?? 0, Util::toInt($nation['totalCrew']));
|
||||
|
||||
if (count($cityNations[$nationID] ?? []) > count($powerValues['maxCities'] ?? [])) {
|
||||
$powerValues['maxCities'] = $cityNations[$nationID];
|
||||
}
|
||||
|
||||
$db->update('nation', [
|
||||
'power' => $nation['power']
|
||||
], 'nation=%i', $nationID);
|
||||
$nationStor->max_power = $powerValues;
|
||||
}
|
||||
|
||||
// 전쟁기한 세팅
|
||||
foreach($db->query('SELECT me, you, dead, term FROM diplomacy WHERE state = 0') as $dip) {
|
||||
$genCount = $genNum[$dip['me']];
|
||||
// 25% 참여율일때 두당 10턴에 4000명 소모한다고 계산
|
||||
// 4000 / 10 * 0.25 = 100
|
||||
$term = floor($dip['dead'] / 100 / $genCount);
|
||||
$dip['dead'] -= $term * 100 * $genCount;
|
||||
$term = Util::valueFit($dip['term'] + $term, 0, 13);
|
||||
|
||||
$db->update('diplomacy', [
|
||||
'term' => $term,
|
||||
'dead' => $dip['dead'],
|
||||
], 'me = %i AND you = %i', $dip['me'], $dip['you']);
|
||||
}
|
||||
|
||||
//개전국 로그
|
||||
foreach($db->query('SELECT me, you FROM diplomacy WHERE state = 1 AND term <= 1 AND me < you') as $dip){
|
||||
$nation1 = getNationStaticInfo($dip['me']);
|
||||
$name1 = $nation1['name'];
|
||||
$nation2 = getNationStaticInfo($dip['you']);
|
||||
$name2 = $nation2['name'];
|
||||
|
||||
$josaYi = JosaUtil::pick($name2, '이');
|
||||
$josaWa = JosaUtil::pick($name1, '와');
|
||||
$globalLogger->pushGlobalHistoryLog("<R><b>【개전】</b></><D><b>$name1</b></>{$josaWa} <D><b>$name2</b></>{$josaYi} <R>전쟁</>을 시작합니다.");
|
||||
}
|
||||
//휴전국 로그
|
||||
$stopWarList = [];
|
||||
foreach($db->queryAllLists('SELECT me,you FROM diplomacy WHERE state=0 AND term <= 1 ORDER BY me desc, you desc') as [$me, $you]){
|
||||
if($me < $you){
|
||||
$key = "{$me}_{$you}";
|
||||
}
|
||||
else{
|
||||
$key = "{$you}_{$me}";
|
||||
}
|
||||
if(!key_exists($key, $stopWarList)){
|
||||
$stopWarList[$key] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//양측 기간 모두 0이 되는 상황이면 휴전
|
||||
$nation1 = getNationStaticInfo($me);
|
||||
$name1 = $nation1['name'];
|
||||
$nation2 = getNationStaticInfo($you);
|
||||
$name2 = $nation2['name'];
|
||||
|
||||
$josaWa = JosaUtil::pick($name1, '와');
|
||||
$josaYi = JosaUtil::pick($name2, '이');
|
||||
|
||||
$globalLogger->pushGlobalHistoryLog("<R><b>【휴전】</b></><D><b>$name1</b></>{$josaWa} <D><b>$name2</b></>{$josaYi} <S>휴전</>합니다.");
|
||||
$db->update('diplomacy', [
|
||||
'state'=>2,
|
||||
'term'=>0,
|
||||
], '(me=%i AND you=%i) OR (you=%i AND me=%i)', $me, $you, $me, $you);
|
||||
}
|
||||
|
||||
$globalLogger->flush();
|
||||
|
||||
//사상자 초기화, 외교 기한-1
|
||||
$db->update('diplomacy', [
|
||||
'dead'=>$db->sqleval('if(state!=0, 0, dead)'),
|
||||
'term'=>$db->sqleval('greatest(0, term-1)'),
|
||||
], true);
|
||||
//불가침 끝나면 통상으로
|
||||
$db->update('diplomacy', [
|
||||
'state'=>2,
|
||||
], 'state = 7 AND term = 0');
|
||||
//선포 끝나면 교전으로
|
||||
$db->update('diplomacy', [
|
||||
'state'=>0,
|
||||
'term'=>6,
|
||||
], 'state = 1 AND term = 0');
|
||||
|
||||
//초반이후 방랑군 자동 해체
|
||||
if ($admin['year'] >= $admin['startyear'] + 2) {
|
||||
checkWander();
|
||||
}
|
||||
// 작위 업데이트
|
||||
updateNationState();
|
||||
updateGeneralNumber();
|
||||
refreshNationStaticInfo();
|
||||
// 천통여부 검사
|
||||
checkEmperior();
|
||||
//토너먼트 개시
|
||||
triggerTournament();
|
||||
// 시스템 거래건 등록
|
||||
registerAuction();
|
||||
//전방설정
|
||||
foreach (getAllNationStaticInfo() as $nation) {
|
||||
if ($nation['level'] <= 0) {
|
||||
continue;
|
||||
}
|
||||
SetNationFront($nation['nation']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkWander()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month']);
|
||||
|
||||
$wanderers = $db->queryFirstColumn('SELECT general.`no` FROM general LEFT JOIN nation ON general.nation = nation.nation WHERE nation.`level` = 0 AND general.`officer_level` = 12');
|
||||
|
||||
foreach (General::createGeneralObjListFromDB($wanderers) as $wanderer) {
|
||||
$wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin);
|
||||
if ($wanderCmd->hasFullConditionMet()) {
|
||||
$logger = $wanderer->getLogger();
|
||||
$logger->pushGeneralActionLog('초반 제한후 방랑군은 자동 해산됩니다.', ActionLogger::PLAIN);
|
||||
$wanderCmd->run();
|
||||
}
|
||||
}
|
||||
|
||||
if ($wanderers) {
|
||||
refreshNationStaticInfo();
|
||||
}
|
||||
}
|
||||
|
||||
function updateNationState()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$history = array();
|
||||
$admin = $gameStor->getValues(['killturn', 'year', 'month', 'fiction', 'startyear', 'show_img_level', 'turnterm', 'turntime']);
|
||||
|
||||
$assemblerCnts = [];
|
||||
foreach ($db->queryAllLists('SELECT nation,count(no) FROM general WHERE npc = 5 GROUP BY nation') as [$nationID, $assemblerCnt]) {
|
||||
$assemblerCnts[$nationID] = $assemblerCnt;
|
||||
};
|
||||
|
||||
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
|
||||
//TODO: level이 진관수이소중대특 체계를 벗어날 수 있음
|
||||
$citycount = $db->queryFirstField('SELECT count(*) FROM city WHERE nation=%i AND level>=4', $nation['nation']);
|
||||
|
||||
if ($citycount == 0) {
|
||||
$nationlevel = 0; // 방랑군
|
||||
} elseif ($citycount == 1) {
|
||||
$nationlevel = 1; // 호족
|
||||
} elseif ($citycount <= 4) {
|
||||
$nationlevel = 2; // 군벌
|
||||
} elseif ($citycount <= 7) {
|
||||
$nationlevel = 3; // 주자사
|
||||
} elseif ($citycount <= 10) {
|
||||
$nationlevel = 4; // 주목
|
||||
} elseif ($citycount <= 15) {
|
||||
$nationlevel = 5; // 공
|
||||
} elseif ($citycount <= 20) {
|
||||
$nationlevel = 6; // 왕
|
||||
} else {
|
||||
$nationlevel = 7; // 황제
|
||||
}
|
||||
|
||||
if ($nationlevel > $nation['level']) {
|
||||
$levelDiff = $nationlevel - $nation['level'];
|
||||
$oldLevel = $nation['level'];
|
||||
$nation['level'] = $nationlevel;
|
||||
|
||||
$updateVals = [
|
||||
'level' => $nationlevel,
|
||||
'gold'=>$db->sqleval('gold + %i', $nationlevel*1000),
|
||||
'rice'=>$db->sqleval('rice + %i', $nationlevel*1000),
|
||||
];
|
||||
|
||||
switch ($nationlevel) {
|
||||
case 7:
|
||||
$josaUl = JosaUtil::pick(getNationLevel($nationlevel), '을');
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭하였습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭"]);
|
||||
$auxVal = Json::decode($nation['aux']);
|
||||
$auxVal['can_국기변경'] = 1;
|
||||
$auxVal['can_국호변경'] = 1;
|
||||
$updateVals['aux'] = Json::encode($auxVal);
|
||||
break;
|
||||
case 6:
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극하였습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극"]);
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
case 3:
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명되었습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명됨"]);
|
||||
break;
|
||||
case 2:
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 독립하여 <Y>" . getNationLevel($nationlevel) . "</>로 나섰습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>로 나서다"]);
|
||||
break;
|
||||
}
|
||||
|
||||
$db->update('nation', $updateVals, 'nation=%i', $nation['nation']);
|
||||
|
||||
$turnRows = [];
|
||||
foreach (Util::range(getNationChiefLevel($nation['level']), 12) as $chiefLevel) {
|
||||
foreach (Util::range(GameConst::$maxChiefTurn) as $turnIdx) {
|
||||
$turnRows[] = [
|
||||
'nation_id' => $nation['nation'],
|
||||
'officer_level' => $chiefLevel,
|
||||
'turn_idx' => $turnIdx,
|
||||
'action' => '휴식',
|
||||
'arg' => null,
|
||||
'brief' => '휴식'
|
||||
];
|
||||
}
|
||||
}
|
||||
$db->insertIgnore('nation_turn', $turnRows);
|
||||
|
||||
if ($levelDiff) {
|
||||
//유니크 아이템 하나 돌리자
|
||||
$targetKillTurn = $admin['killturn'];
|
||||
$targetKillTurn -= 24 * 60 / $admin['turnterm'];
|
||||
$nationGenIDList = $db->queryFirstColumn(
|
||||
'SELECT no FROM general WHERE nation = %i AND killturn >= %i AND npc < 2',
|
||||
$nation['nation'],
|
||||
$targetKillTurn
|
||||
);
|
||||
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong'], 2);
|
||||
|
||||
$uniqueLotteryWeightList = [];
|
||||
foreach ($nationGenList as $nationGen) {
|
||||
$hasUnique = false;
|
||||
foreach ($nationGen->getItems() as $item) {
|
||||
if (!$item->isBuyable()) {
|
||||
$hasUnique = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($hasUnique) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$score = $nationGen->getVar('belong') + 5;
|
||||
|
||||
if ($nationGen->getVar('officer_level') == 12) {
|
||||
$score += 200; //NOTE: 꼬우면 군주하세요.
|
||||
} else if ($nationGen->getVar('officer_level') == 11) {
|
||||
$score += 70;
|
||||
} else if ($nationGen->getVar('officer_level') > 4) {
|
||||
$score += 35;
|
||||
}
|
||||
$uniqueLotteryWeightList[$nationGen->getID()] = [$nationGen, $score];
|
||||
}
|
||||
|
||||
foreach (Util::range($levelDiff) as $idx) {
|
||||
if (!$uniqueLotteryWeightList) {
|
||||
break;
|
||||
}
|
||||
|
||||
/** @var General */
|
||||
$winnerObj = Util::choiceRandomUsingWeightPair($uniqueLotteryWeightList);
|
||||
unset($uniqueLotteryWeightList[$winnerObj->getID()]);
|
||||
giveRandomUniqueItem($winnerObj, '작위보상');
|
||||
$winnerObj->applyDB($db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$assemblerCnt = $assemblerCnts[$nation['nation']] ?? 0;
|
||||
$maxAssemblerCnt = [
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 6,
|
||||
6 => 7,
|
||||
7 => 9
|
||||
][$nationlevel] ?? 0;
|
||||
|
||||
if ($assemblerCnt < $maxAssemblerCnt) {
|
||||
$lastAssemblerID = $gameStor->assembler_id ?? 0;
|
||||
|
||||
while ($assemblerCnt < $maxAssemblerCnt) {
|
||||
$lastAssemblerID += 1;
|
||||
$npcObj = new Scenario\NPC(
|
||||
999,
|
||||
sprintf('부대장%4d', $lastAssemblerID),
|
||||
null,
|
||||
$nation['nation'],
|
||||
null,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
1,
|
||||
$admin['year'] - 15,
|
||||
$admin['year'] + 15,
|
||||
'은둔',
|
||||
'척사'
|
||||
);
|
||||
$npcObj->killturn = 70;
|
||||
$npcObj->gold = 0;
|
||||
$npcObj->rice = 0;
|
||||
$npcObj->npc = 5;
|
||||
$npcObj->build($admin);
|
||||
$npcID = $npcObj->generalID;
|
||||
|
||||
$db->insert('troop', [
|
||||
'troop_leader' => $npcID,
|
||||
'name' => $npcObj->realName,
|
||||
'nation' => $nation['nation'],
|
||||
]);
|
||||
$db->update('general', [
|
||||
'troop' => $npcID
|
||||
], 'no=%i', $npcID);
|
||||
|
||||
$cmd = buildGeneralCommandClass('che_집합', General::createGeneralObjFromDB($npcID), $admin);
|
||||
_setGeneralCommand($cmd, iterator_to_array(Util::range(GameConst::$maxTurn)));
|
||||
$assemblerCnt += 1;
|
||||
$gameStor->assembler_id = $lastAssemblerID;
|
||||
}
|
||||
}
|
||||
}
|
||||
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
|
||||
}
|
||||
|
||||
function checkStatistic()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month']);
|
||||
|
||||
$nationHists = [];
|
||||
$specialHists = [];
|
||||
$personalHists = [];
|
||||
$specialHists2 = [];
|
||||
$crewtypeHists = [];
|
||||
|
||||
$etc = '';
|
||||
|
||||
$auxData = [
|
||||
'generals' => [],
|
||||
'nations' => [],
|
||||
];
|
||||
|
||||
$avgGeneral = $db->queryFirstRow(
|
||||
'SELECT avg(gold) as avggold, avg(rice) as avgrice, avg(dex1+dex2+dex3+dex4) as avgdex,
|
||||
max(dex1+dex2+dex3+dex4) as maxdex, avg(experience+dedication) as avgexpded, max(experience+dedication) as maxexpded
|
||||
FROM general'
|
||||
);
|
||||
$auxData['generals']['avg'] = $avgGeneral;
|
||||
|
||||
$avgGeneral['avggold'] = Util::round($avgGeneral['avggold']);
|
||||
$avgGeneral['avgrice'] = Util::round($avgGeneral['avgrice']);
|
||||
$avgGeneral['avgdex'] = Util::round($avgGeneral['avgdex']);
|
||||
$avgGeneral['avgexpded'] = Util::round($avgGeneral['avgexpded']);
|
||||
$etc .= "평균 금/쌀 ({$avgGeneral['avggold']}/{$avgGeneral['avgrice']}), 평균/최고 숙련({$avgGeneral['avgdex']}/{$avgGeneral['maxdex']}), 평균/최고 경험공헌({$avgGeneral['avgexpded']}/{$avgGeneral['maxexpded']}), ";
|
||||
|
||||
$avgNation = $db->queryFirstRow(
|
||||
'SELECT min(tech) as mintech, max(tech) as maxtech, avg(tech) as avgtech,
|
||||
min(power) as minpower, max(power) as maxpower, avg(power) as avgpower from nation where level>0'
|
||||
);
|
||||
$auxData['nations']['avg'] = $avgNation;
|
||||
|
||||
$avgNation['mintech'] = floor($avgNation['mintech']);
|
||||
$avgNation['maxtech'] = floor($avgNation['maxtech']);
|
||||
$avgNation['avgtech'] = Util::round($avgNation['avgtech']);
|
||||
$avgNation['avgpower'] = Util::round($avgNation['avgpower']);
|
||||
$etc .= "최저/평균/최고 기술({$avgNation['mintech']}/{$avgNation['avgtech']}/{$avgNation['maxtech']}), ";
|
||||
$etc .= "최저/평균/최고 국력({$avgNation['minpower']}/{$avgNation['avgpower']}/{$avgNation['maxpower']}), ";
|
||||
|
||||
$nationName = '';
|
||||
$powerHist = '';
|
||||
|
||||
$nations = Util::convertArrayToDict(
|
||||
$db->query(
|
||||
'SELECT nation,name,type,power,gennum,gold+rice as goldrice from nation where level>0 order by power desc',
|
||||
'nation'
|
||||
),
|
||||
'nation'
|
||||
);
|
||||
$nationCount = count($nations);
|
||||
|
||||
$nationGeneralInfos = Util::convertArrayToDict(
|
||||
$db->query(
|
||||
'SELECT nation, sum(leadership+strength+intel) as abil,sum(gold+rice) as goldrice,
|
||||
sum(dex1+dex2+dex3+dex4) as dex,sum(experience+dedication) as expded
|
||||
from general GROUP BY nation'
|
||||
),
|
||||
'nation'
|
||||
);
|
||||
|
||||
$nationCityInfos = Util::convertArrayToDict(
|
||||
$db->query('SELECT nation, count(*) as cnt, sum(pop) as pop,sum(pop_max) as pop_max from city GROUP BY nation'),
|
||||
'nation'
|
||||
);
|
||||
|
||||
foreach ($nations as $nationNo => &$nation) {
|
||||
$general = $nationGeneralInfos[$nationNo];
|
||||
$city = $nationCityInfos[$nationNo];
|
||||
|
||||
$nation['generalInfo'] = $general;
|
||||
$nation['cityInfo'] = $city;
|
||||
|
||||
$nationName .= $nation['name'] . '(' . getNationType($nation['type']) . '), ';
|
||||
$powerHist .= "{$nation['name']}({$nation['power']}/{$nation['gennum']}/{$city['cnt']}/{$city['pop']}/{$city['pop_max']}/{$nation['goldrice']}/{$general['goldrice']}/{$general['abil']}/{$general['dex']}/{$general['expded']}), ";
|
||||
|
||||
if (!isset($nationHists[$nation['type']])) {
|
||||
$nationHists[$nation['type']] = 0;
|
||||
}
|
||||
$nationHists[$nation['type']]++;
|
||||
}
|
||||
unset($nation);
|
||||
|
||||
$auxData['nations']['all'] = $nations;
|
||||
|
||||
$nationHist = '';
|
||||
foreach (GameConst::$availableNationType as $nationType) {
|
||||
if (!Util::array_get($nationHists[$nationType])) {
|
||||
$nationHists[$nationType] = '-';
|
||||
}
|
||||
$nationHist .= getNationType($nationType) . "({$nationHists[$nationType]}), ";
|
||||
}
|
||||
|
||||
$generals = $db->query('SELECT `no`,npc,personal,special,special2,crewtype FROM general');
|
||||
|
||||
$genCount = 0;
|
||||
$npcCount = 0;
|
||||
$generalCount = count($generals);
|
||||
|
||||
foreach ($generals as $general) {
|
||||
if (!isset($personalHists[$general['personal']])) {
|
||||
$personalHists[$general['personal']] = 0;
|
||||
}
|
||||
|
||||
if (!isset($specialHists[$general['special']])) {
|
||||
$specialHists[$general['special']] = 0;
|
||||
}
|
||||
|
||||
if (!isset($specialHists2[$general['special2']])) {
|
||||
$specialHists2[$general['special2']] = 0;
|
||||
}
|
||||
|
||||
if ($general['npc'] < 2) {
|
||||
$genCount += 1;
|
||||
} else {
|
||||
$npcCount += 1;
|
||||
}
|
||||
|
||||
$personalHists[$general['personal']]++;
|
||||
$specialHists[$general['special']]++;
|
||||
$specialHists2[$general['special2']]++;
|
||||
}
|
||||
|
||||
foreach ($db->queryAllLists(
|
||||
'SELECT crewtype, count(crewtype) AS cnt FROM general WHERE recent_war != NULL GROUP BY crewtype'
|
||||
) as [$crewtype, $cnt]) {
|
||||
$crewtypeHists[$crewtype] = $cnt;
|
||||
}
|
||||
|
||||
$auxData['generals']['hists'] = [
|
||||
'personal' => $personalHists,
|
||||
'special' => $specialHists,
|
||||
'special2' => $specialHists2,
|
||||
'crewtype' => $crewtypeHists,
|
||||
'userCnt' => $genCount,
|
||||
'npcCnt' => $npcCount,
|
||||
];
|
||||
|
||||
$generalCountStr = "{$generalCount}({$genCount}+{$npcCount})";
|
||||
|
||||
$personalHistStr = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return getGenChar($histKey) . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($personalHists)));
|
||||
|
||||
$specialHistsStr = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return getGeneralSpecialDomesticName($histKey) . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($specialHists)));
|
||||
|
||||
$specialHists2Str = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return getGeneralSpecialWarName($histKey) . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($specialHists2)));
|
||||
|
||||
$specialHistsAllStr = "$specialHistsStr // $specialHists2Str";
|
||||
|
||||
$crewtypeHistsStr = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return GameUnitConst::byID($histKey)->getShortName() . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($crewtypeHists)));
|
||||
|
||||
$db->insert('statistic', [
|
||||
'year' => $admin['year'],
|
||||
'month' => $admin['month'],
|
||||
'nation_count' => $nationCount,
|
||||
'nation_name' => $nationName,
|
||||
'nation_hist' => $nationHist,
|
||||
'gen_count' => $generalCountStr,
|
||||
'personal_hist' => $personalHistStr,
|
||||
'special_hist' => $specialHistsAllStr,
|
||||
'power_hist' => $powerHist,
|
||||
'crewtype' => $crewtypeHistsStr,
|
||||
'etc' => $etc,
|
||||
'aux' => Json::encode($auxData)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
function convForOldGeneral(array $general, int $year, int $month)
|
||||
{
|
||||
$general['history'] = getGeneralHistoryLogAll($general['no']);
|
||||
return [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'general_no' => $general['no'],
|
||||
'owner' => $general['owner'],
|
||||
'name' => $general['name'],
|
||||
'last_yearmonth' => $year * 100 + $month,
|
||||
'turntime' => $general['turntime'],
|
||||
'data' => Json::encode($general)
|
||||
];
|
||||
}
|
||||
|
||||
function storeOldGeneral(int $no, int $year, int $month)
|
||||
{
|
||||
$db = DB::db();
|
||||
$general = $db->queryFirstRow('SELECT * FROM general WHERE `no` = %i', $no);
|
||||
if (!$general) {
|
||||
return;
|
||||
}
|
||||
$data = convForOldGeneral($general, $year, $month);
|
||||
$db->insertUpdate(
|
||||
'ng_old_generals',
|
||||
$data,
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
function storeOldGenerals(int $nation, int $year, int $month)
|
||||
{
|
||||
$db = DB::db();
|
||||
foreach ($db->query('SELECT * FROM general WHERE nation = %i', $nation) as $general) {
|
||||
$data = convForOldGeneral($general, $year, $month);
|
||||
$db->insertUpdate(
|
||||
'ng_old_generals',
|
||||
$data,
|
||||
$data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function checkEmperior()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'conlimit']);
|
||||
if ($admin['isunited'] != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$remainNations = $db->queryFirstColumn('SELECT nation FROM nation WHERE level > 0 LIMIT 2');
|
||||
|
||||
if (!$remainNations || count($remainNations) != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nationID = $remainNations[0];
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
$cityCnt = $db->queryFirstField('SELECT count(city) FROM city WHERE nation=%i', $nationID);
|
||||
if (!$cityCnt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($cityCnt != count(CityConst::all())) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkStatistic();
|
||||
|
||||
$nation = $db->queryFirstRow('SELECT * FROM nation WHERE nation=%i', $nationID);
|
||||
$nationName = $nation['name'];
|
||||
|
||||
$josaYi = JosaUtil::pick($nationName, '이');
|
||||
|
||||
$nationLogger = new ActionLogger(0, $nationID, $admin['year'], $admin['month']);
|
||||
$nationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일");
|
||||
|
||||
$gameStor->isunited = 2;
|
||||
$gameStor->conlimit = $gameStor->conlimit * 100;
|
||||
|
||||
foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) {
|
||||
CheckHall($hallGeneralNo);
|
||||
}
|
||||
|
||||
[$totalPop, $totalMaxPop] = $db->queryFirstList('SELECT SUM(pop), SUM(pop_max) FROM city');
|
||||
$pop = "{$totalPop} / {$totalMaxPop}";
|
||||
$poprate = round($totalPop / $totalMaxPop * 100, 2). " %";
|
||||
|
||||
$chiefs = Util::convertArrayToDict(
|
||||
$db->query(
|
||||
'SELECT no,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5',
|
||||
$nationID
|
||||
),
|
||||
'officer_level'
|
||||
);
|
||||
|
||||
$nationGenerals = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=%i', $nationID);
|
||||
$nation['generals'] = $nationGenerals;
|
||||
|
||||
$tigers = $db->query(
|
||||
'SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "killnum" AND value > 0 ORDER BY value DESC LIMIT 5',
|
||||
$nationID
|
||||
); // 오호장군
|
||||
|
||||
$tigerstr = join(', ', array_map(function ($arr) {
|
||||
$number = number_format($arr['value']);
|
||||
return "{$arr['name']}【{$number}】";
|
||||
}, $tigers));
|
||||
|
||||
$eagles = $db->query(
|
||||
'SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "firenum" AND value > 0 ORDER BY value DESC LIMIT 7',
|
||||
$nationID
|
||||
); // 건안칠자
|
||||
|
||||
$eaglestr = join(', ', array_map(function ($arr) {
|
||||
$number = number_format($arr['value']);
|
||||
return "{$arr['name']}【{$number}】";
|
||||
}, $eagles));
|
||||
|
||||
$rawGeneralList = $db->query('SELECT no, name, npc, owner FROM general WHERE nation=%i ORDER BY dedication DESC', $nationID);
|
||||
foreach ($rawGeneralList as $rawGeneral) {
|
||||
$generalLogger = new ActionLogger($rawGeneral['no'], $nationID, $admin['year'], $admin['month']);
|
||||
$generalLogger->pushGeneralActionLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일하였습니다.", ActionLogger::YEAR_MONTH);
|
||||
$generalLogger->flush();
|
||||
}
|
||||
|
||||
$gen = join(', ', array_column($rawGeneral, 'name'));
|
||||
|
||||
$stat = $db->queryFirstRow('SELECT max(nation_count) as nc, max(gen_count) as gc FROM statistic');
|
||||
$genCnt = $db->queryFirstField('SELECT count(*) FROM general');
|
||||
|
||||
$statNC = "1 / {$stat['nc']}";
|
||||
$statGC = "{$genCnt} / {$stat['gc']}";
|
||||
$statNation = $db->queryFirstRow('SELECT nation_count,nation_name,nation_hist from statistic where nation_count=%i LIMIT 1', $stat['nc']);
|
||||
$statGeneral = $db->queryFirstRow('SELECT gen_count,personal_hist,special_hist,aux from statistic order by no desc LIMIT 1');
|
||||
|
||||
$nation = $nation;
|
||||
$nation['generals'] = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=%i', $nation['nation']);
|
||||
$nation['aux'] = Json::decode($nation['aux']);
|
||||
$nation['msg'] = $nationStor->notice;
|
||||
$nation['scout_msg'] = $nationStor->scout_msg;
|
||||
$nation['aux'] += $nationStor->max_power;
|
||||
$nation['history'] = getNationHistoryLogAll($nation['nation']);
|
||||
|
||||
storeOldGenerals(0, $admin['year'], $admin['month']);
|
||||
storeOldGenerals($nation['nation'], $admin['year'], $admin['month']);
|
||||
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => $nation['nation'],
|
||||
'data' => Json::encode($nation)
|
||||
]);
|
||||
|
||||
$noNationGeneral = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=0');
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => 0,
|
||||
'data' => Json::encode([
|
||||
'nation' => 0,
|
||||
'name' => '재야',
|
||||
'generals' => $noNationGeneral
|
||||
])
|
||||
]);
|
||||
|
||||
$nationHistory = getNationHistoryLogAll($nation['nation']);
|
||||
|
||||
$serverCnt = $db->queryFirstField('SELECT count(*) FROM ng_games');
|
||||
$serverName = UniqueConst::$serverName;
|
||||
|
||||
$db->update('ng_games', [
|
||||
'winner_nation' => $nation['nation']
|
||||
], 'server_id=%s', UniqueConst::$serverID);
|
||||
|
||||
$db->insert('emperior', [
|
||||
'phase' => $serverName . $serverCnt . '기',
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation_count' => $statNC,
|
||||
'nation_name' => $statNation['nation_name'],
|
||||
'nation_hist' => $statNation['nation_hist'],
|
||||
'gen_count' => $statGC,
|
||||
'personal_hist' => $statGeneral['personal_hist'],
|
||||
'special_hist' => $statGeneral['special_hist'],
|
||||
'name' => $nation['name'],
|
||||
'type' => $nation['type'],
|
||||
'color' => $nation['color'],
|
||||
'year' => $admin['year'],
|
||||
'month' => $admin['month'],
|
||||
'power' => $nation['power'],
|
||||
'gennum' => $nation['gennum'],
|
||||
'citynum' => $cityCnt,
|
||||
'pop' => $pop,
|
||||
'poprate' => $poprate,
|
||||
'gold' => $nation['gold'],
|
||||
'rice' => $nation['rice'],
|
||||
'l12name' => $chiefs[12]['name'],
|
||||
'l12pic' => $chiefs[12]['picture'],
|
||||
'l11name' => $chiefs[11]['name'],
|
||||
'l11pic' => $chiefs[11]['picture'],
|
||||
'l10name' => $chiefs[10]['name'],
|
||||
'l10pic' => $chiefs[10]['picture'],
|
||||
'l9name' => $chiefs[9]['name'],
|
||||
'l9pic' => $chiefs[9]['picture'],
|
||||
'l8name' => $chiefs[8]['name'],
|
||||
'l8pic' => $chiefs[8]['picture'],
|
||||
'l7name' => $chiefs[7]['name'],
|
||||
'l7pic' => $chiefs[7]['picture'],
|
||||
'l6name' => $chiefs[6]['name'],
|
||||
'l6pic' => $chiefs[6]['picture'],
|
||||
'l5name' => $chiefs[5]['name'],
|
||||
'l5pic' => $chiefs[5]['picture'],
|
||||
'tiger' => $tigerstr,
|
||||
'eagle' => $eaglestr,
|
||||
'gen' => $gen,
|
||||
'history' => JSON::encode($nationHistory),
|
||||
'aux' => $statGeneral['aux']
|
||||
]);
|
||||
|
||||
$history = ["<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【통일】</b></><D><b>{$nation['name']}</b></>{$josaYi} 전토를 통일하였습니다."];
|
||||
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
|
||||
|
||||
//연감 월결산
|
||||
LogHistory();
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use Monolog\Logger;
|
||||
|
||||
/**
|
||||
* 게임 룰에 해당하는 함수 모음
|
||||
*/
|
||||
|
||||
function getNationLevelList(): array
|
||||
{
|
||||
$table = [
|
||||
0 => ['방랑군', 2, 0],
|
||||
1 => ['호족', 2, 1],
|
||||
2 => ['군벌', 4, 2],
|
||||
3 => ['주자사', 4, 5],
|
||||
4 => ['주목', 6, 8],
|
||||
5 => ['공', 6, 11],
|
||||
6 => ['왕', 8, 16],
|
||||
7 => ['황제', 8, 21],
|
||||
];
|
||||
return $table;
|
||||
}
|
||||
|
||||
function getCityLevelList(): array
|
||||
{
|
||||
return [
|
||||
1 => '수',
|
||||
2 => '진',
|
||||
3 => '관',
|
||||
4 => '이',
|
||||
5 => '소',
|
||||
6 => '중',
|
||||
7 => '대',
|
||||
8 => '특'
|
||||
];
|
||||
}
|
||||
|
||||
//한국가의 전체 전방 설정
|
||||
function SetNationFront($nationNo)
|
||||
{
|
||||
if (!$nationNo) {
|
||||
return;
|
||||
}
|
||||
// 도시소유 국가와 선포,교전중인 국가
|
||||
|
||||
$adj3 = [];
|
||||
$adj2 = [];
|
||||
$adj1 = [];
|
||||
|
||||
$db = DB::db();
|
||||
foreach ($db->queryFirstColumn(
|
||||
'SELECT city FROM city JOIN diplomacy ON diplomacy.you = city.nation WHERE diplomacy.state = 0 AND me = %i',
|
||||
$nationNo
|
||||
) as $city) {
|
||||
foreach (CityConst::byID($city)->path as $adjKey => $adjVal) {
|
||||
$adj3[$adjKey] = $adjVal;
|
||||
}
|
||||
};
|
||||
foreach ($db->queryFirstColumn(
|
||||
'SELECT city FROM city JOIN diplomacy ON diplomacy.you = city.nation WHERE diplomacy.state = 1 AND diplomacy.term <= 5 AND me = %i',
|
||||
$nationNo
|
||||
) as $city) {
|
||||
foreach (CityConst::byID($city)->path as $adjKey => $adjVal) {
|
||||
$adj1[$adjKey] = $adjVal;
|
||||
}
|
||||
}
|
||||
if (!$adj3 && !$adj1) {
|
||||
//평시이면 공백지
|
||||
//NOTE: if, else일 경우 NPC는 전쟁시에는 공백지로 출병하지 않는다는 뜻이 된다.
|
||||
foreach ($db->queryFirstColumn('SELECT city from city where nation=0') as $city) {
|
||||
foreach (CityConst::byID($city)->path as $adjKey => $adjVal) {
|
||||
$adj2[$adjKey] = $adjVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$db->update('city', [
|
||||
'front' => 0
|
||||
], 'nation=%i', $nationNo);
|
||||
|
||||
if ($adj1) {
|
||||
$db->update('city', [
|
||||
'front' => 1,
|
||||
], 'nation=%i and city in %li', $nationNo, array_keys($adj1));
|
||||
}
|
||||
if ($adj2) {
|
||||
$db->update('city', [
|
||||
'front' => 2,
|
||||
], 'nation=%i and city in %li', $nationNo, array_keys($adj2));
|
||||
}
|
||||
if ($adj3) {
|
||||
$db->update('city', [
|
||||
'front' => 3,
|
||||
], 'nation=%i and city in %li', $nationNo, array_keys($adj3));
|
||||
}
|
||||
}
|
||||
|
||||
function checkSupply()
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$cities = [];
|
||||
foreach ($db->query('SELECT city, nation FROM city WHERE nation != 0') as $city) {
|
||||
$newCity = new \stdClass();
|
||||
$newCity->id = Util::toInt($city['city']);
|
||||
$newCity->nation = Util::toInt($city['nation']);
|
||||
$newCity->supply = false;
|
||||
|
||||
$cities[$newCity->id] = $newCity;
|
||||
}
|
||||
|
||||
$queue = new \SplQueue();
|
||||
foreach ($db->queryAllLists('SELECT capital, nation FROM nation WHERE `level` > 0') as list($capitalID, $nationID)) {
|
||||
if (!key_exists($capitalID, $cities)) {
|
||||
continue;
|
||||
}
|
||||
$city = $cities[$capitalID];
|
||||
if ($nationID != $city->nation) {
|
||||
continue;
|
||||
}
|
||||
$city->supply = true;
|
||||
$queue->enqueue($city);
|
||||
}
|
||||
|
||||
while (!$queue->isEmpty()) {
|
||||
$cityLink = $queue->dequeue();
|
||||
$city = CityConst::byID($cityLink->id);
|
||||
|
||||
foreach (array_keys($city->path) as $connCityID) {
|
||||
if (!key_exists($connCityID, $cities)) {
|
||||
continue;
|
||||
}
|
||||
$connCity = $cities[$connCityID];
|
||||
if ($connCity->nation != $cityLink->nation) {
|
||||
continue;
|
||||
}
|
||||
if ($connCity->supply) {
|
||||
continue;
|
||||
}
|
||||
$connCity->supply = true;
|
||||
$queue->enqueue($connCity);
|
||||
}
|
||||
}
|
||||
|
||||
$db->update('city', [
|
||||
'supply' => 1
|
||||
], 'nation=0');
|
||||
|
||||
$db->update('city', [
|
||||
'supply' => 0
|
||||
], 'nation!=0');
|
||||
|
||||
$supply = [];
|
||||
|
||||
foreach ($cities as $city) {
|
||||
if ($city->supply) {
|
||||
$supply[] = $city->id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($supply) {
|
||||
$db->update('city', [
|
||||
'supply' => 1
|
||||
], 'city IN %li', $supply);
|
||||
}
|
||||
}
|
||||
|
||||
function updateGeneralNumber()
|
||||
{
|
||||
$db = DB::db();
|
||||
foreach ($db->queryAllLists('SELECT nation, count(*) FROM general WHERE npc != 5 GROUP BY nation') as [$nationID, $gennum]) {
|
||||
if ($nationID === 0) {
|
||||
continue;
|
||||
}
|
||||
$db->update('nation', [
|
||||
'gennum' => $gennum
|
||||
], 'nation=%i', $nationID);
|
||||
}
|
||||
refreshNationStaticInfo();
|
||||
}
|
||||
|
||||
function updateYearly()
|
||||
{
|
||||
//통계
|
||||
checkStatistic();
|
||||
}
|
||||
|
||||
//관직 변경 해제
|
||||
function updateQuaterly()
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
//천도 제한 해제, 관직 변경 제한 해제
|
||||
$db->update('nation', [
|
||||
'chief_set' => 0,
|
||||
], true);
|
||||
//관직 변경 제한 해제
|
||||
$db->update('city', [
|
||||
'officer_set' => 0,
|
||||
], true);
|
||||
}
|
||||
|
||||
// 벌점 감소와 건국제한-1 전턴제한-1 외교제한-1, 1달마다 실행, 병사 있는 장수의 군량 감소, 수입비율 조정
|
||||
function preUpdateMonthly()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
//연감 월결산
|
||||
$result = LogHistory();
|
||||
|
||||
if ($result == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$admin = $gameStor->getValues(['startyear', 'year', 'month']);
|
||||
$logger = new ActionLogger(0, 0, $admin['year'], $admin['month']);
|
||||
|
||||
//보급선 체크
|
||||
checkSupply();
|
||||
//미보급도시 10% 감소
|
||||
$db->update('city', [
|
||||
'pop' => $db->sqleval('pop * 0.9'),
|
||||
'trust' => $db->sqleval('trust * 0.9'),
|
||||
'agri' => $db->sqleval('agri * 0.9'),
|
||||
'comm' => $db->sqleval('comm * 0.9'),
|
||||
'secu' => $db->sqleval('secu * 0.9'),
|
||||
'def' => $db->sqleval('def * 0.9'),
|
||||
'wall' => $db->sqleval('wall * 0.9'),
|
||||
], 'supply = 0');
|
||||
//미보급도시 장수 병 훈 사 5%감소
|
||||
//NOTE: update inner join도 가능하지만, meekrodb 기준으로 깔끔하게.
|
||||
$unsuppliedCities = $db->query('SELECT city, nation, trust, name FROM city WHERE supply = 0');
|
||||
foreach (Util::arrayGroupBy($unsuppliedCities, 'nation') as $nationID => $cityList) {
|
||||
$cityIDList = Util::squeezeFromArray($cityList, 'city');
|
||||
$db->update('general', [
|
||||
'crew' => $db->sqleval('crew*0.95'),
|
||||
'atmos' => $db->sqleval('atmos*0.95'),
|
||||
'train' => $db->sqleval('train*0.95'),
|
||||
], 'city IN %li AND nation = %i', $cityIDList, $nationID);
|
||||
}
|
||||
|
||||
//민심30이하 공백지 처리
|
||||
$lostCities = [];
|
||||
foreach ($unsuppliedCities as $unsuppliedCity) {
|
||||
if ($unsuppliedCity['trust'] >= 30) {
|
||||
continue;
|
||||
}
|
||||
$lostCities[$unsuppliedCity['city']] = $unsuppliedCity;
|
||||
}
|
||||
|
||||
if ($lostCities) {
|
||||
foreach ($lostCities as $lostCity) {
|
||||
$josaYi = JosaUtil::pick($lostCity['name'], '이');
|
||||
$logger->pushGlobalHistoryLog("<R><b>【고립】</b></><G><b>{$lostCity['name']}</b></>{$josaYi} 보급이 끊겨 <R>미지배</> 도시가 되었습니다.");
|
||||
}
|
||||
$db->update('general', [
|
||||
'officer_level' => 1,
|
||||
'officer_city' => 0
|
||||
], 'officer_city IN %li', array_keys($lostCities));
|
||||
$db->update('city', [
|
||||
'nation' => 0,
|
||||
'officer_set' => 0,
|
||||
'conflict' => '{}',
|
||||
'term' => 0,
|
||||
'front' => 0
|
||||
], 'city IN %li', array_keys($lostCities));
|
||||
}
|
||||
|
||||
//접률감소, 건국제한-1
|
||||
$db->update('general', [
|
||||
'connect' => $db->sqleval('floor(connect*0.99)'),
|
||||
'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'),
|
||||
], true);
|
||||
//전략제한-1, 외교제한-1, 세율동기화
|
||||
$db->update('nation', [
|
||||
'strategic_cmd_limit' => $db->sqleval('greatest(0, strategic_cmd_limit - 1)'),
|
||||
'surlimit' => $db->sqleval('greatest(0, surlimit - 1)'),
|
||||
'rate_tmp' => $db->sqleval('rate')
|
||||
], true);
|
||||
|
||||
//도시훈사 180년 60, 220년 87, 240년 100
|
||||
$rate = Util::round(($admin['year'] - $admin['startyear']) / 1.5) + 60;
|
||||
if ($rate > 100) $rate = 100;
|
||||
|
||||
// 20 ~ 140원
|
||||
$develcost = ($admin['year'] - $admin['startyear'] + 10) * 2;
|
||||
$gameStor->city_rate = $rate;
|
||||
$gameStor->develcost = $develcost;
|
||||
|
||||
//매달 사망자 수입 결산
|
||||
processWarIncome();
|
||||
|
||||
//계략, 전쟁표시 해제
|
||||
$db->update('city', [
|
||||
'state' => $db->sqleval(<<<EOD
|
||||
(CASE
|
||||
WHEN state=31 THEN 0
|
||||
WHEN state=32 THEN 31
|
||||
WHEN state=33 THEN 0
|
||||
WHEN state=34 THEN 33
|
||||
WHEN state=41 THEN 0
|
||||
WHEN state=42 THEN 41
|
||||
WHEN state=43 THEN 42
|
||||
ELSE state END)
|
||||
EOD),
|
||||
'term' => $db->sqleval('greatest(0, term - 1)'),
|
||||
'conflict' => $db->sqleval('if(term = 0,%s,conflict)', '{}'),
|
||||
], true);
|
||||
|
||||
//첩보-1
|
||||
foreach ($db->queryAllLists("SELECT nation, spy FROM nation WHERE spy!='' AND spy!='{}'") as [$nationNo, $rawSpy]) {
|
||||
$spyInfo = Json::decode($rawSpy);
|
||||
|
||||
foreach ($spyInfo as $cityNo => $remainMonth) {
|
||||
if ($remainMonth <= 1) {
|
||||
unset($spyInfo[$cityNo]);
|
||||
} else {
|
||||
$spyInfo[$cityNo] -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
$db->update('nation', [
|
||||
'spy' => Json::encode($spyInfo, Json::EMPTY_ARRAY_IS_DICT)
|
||||
], 'nation=%i', $nationNo);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// 외교 로그처리, 외교 상태 처리
|
||||
function postUpdateMonthly()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['startyear', 'year', 'month', 'scenario']);
|
||||
$globalLogger = new ActionLogger(0, 0, $admin['year'], $admin['month']);
|
||||
|
||||
//도시 수 측정
|
||||
$cityNations = [];
|
||||
foreach ($db->queryAllLists('SELECT city, name, nation FROM city') as [$cityID, $cityName, $cityNation]) {
|
||||
if (!key_exists($cityNation, $cityNations)) {
|
||||
$cityNations[$cityNation] = [];
|
||||
}
|
||||
$cityNations[$cityNation][] = $cityName;
|
||||
}
|
||||
|
||||
//각 국가 전월 장수수 대비 당월 장수수로 단합도 산정
|
||||
//각 국가 장수수를 구하고 국력 산정
|
||||
// $query = "select nation,gennum from nation where level>0";
|
||||
// 국력=
|
||||
// 자원(국가/장수의 금,쌀)
|
||||
// 기술력
|
||||
// 인구수*내정%
|
||||
// 장수능력
|
||||
// 접속률
|
||||
// 숙련도
|
||||
// 명성,공헌
|
||||
$nations = Util::convertArrayToDict($db->query('SELECT
|
||||
A.nation,
|
||||
A.gennum,
|
||||
round((
|
||||
round(((A.gold+A.rice)+(select sum(gold+rice) from general where nation=A.nation))/100)
|
||||
+A.tech
|
||||
+if(A.level=0,0,(
|
||||
select round(
|
||||
sum(pop)*sum(pop+agri+comm+secu+wall+def)/sum(pop_max+agri_max+comm_max+secu_max+wall_max+def_max)/100
|
||||
) from city where nation=A.nation and supply=1
|
||||
))
|
||||
+(select SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`npc` < 2 THEN 1.5 ELSE 1 END)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)*2 + (SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/2)
|
||||
FROM general AS g
|
||||
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = \'killcrew_person\'
|
||||
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = \'deathcrew_person\'
|
||||
WHERE g.nation = A.nation)
|
||||
+(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation)
|
||||
+(select round(sum(experience+dedication)/100) from general where nation=A.nation)
|
||||
+(select round(avg(connect)) from general where nation=A.nation)
|
||||
)/10)
|
||||
as power,
|
||||
(select sum(crew) from general where nation=A.nation) as totalCrew
|
||||
from nation A
|
||||
group by A.nation'), 'nation');
|
||||
$maxPowerValues = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'max_power');
|
||||
|
||||
foreach ($nations as $nation) {
|
||||
$nationID = $nation['nation'];
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$genNum[$nationID] = $nation['gennum'];
|
||||
|
||||
$powerValues = $maxPowerValues[$nationID] ?? [];
|
||||
|
||||
//약간의 랜덤치 부여 (95% ~ 105%)
|
||||
|
||||
$nation['power'] = Util::round($nation['power'] * (rand() % 101 + 950) / 1000);
|
||||
$powerValues['maxPower'] = max($powerValues['maxPower'] ?? 0, $nation['power']);
|
||||
$powerValues['maxCrew'] = max($powerValues['maxCrew'] ?? 0, Util::toInt($nation['totalCrew']));
|
||||
|
||||
if (count($cityNations[$nationID] ?? []) > count($powerValues['maxCities'] ?? [])) {
|
||||
$powerValues['maxCities'] = $cityNations[$nationID];
|
||||
}
|
||||
|
||||
$db->update('nation', [
|
||||
'power' => $nation['power']
|
||||
], 'nation=%i', $nationID);
|
||||
$nationStor->max_power = $powerValues;
|
||||
}
|
||||
|
||||
// 전쟁기한 세팅
|
||||
foreach ($db->query('SELECT me, you, dead, term FROM diplomacy WHERE state = 0') as $dip) {
|
||||
$genCount = $genNum[$dip['me']];
|
||||
// 25% 참여율일때 두당 10턴에 4000명 소모한다고 계산
|
||||
// 4000 / 10 * 0.25 = 100
|
||||
$term = floor($dip['dead'] / 100 / $genCount);
|
||||
$dip['dead'] -= $term * 100 * $genCount;
|
||||
$term = Util::valueFit($dip['term'] + $term, 0, 13);
|
||||
|
||||
$db->update('diplomacy', [
|
||||
'term' => $term,
|
||||
'dead' => $dip['dead'],
|
||||
], 'me = %i AND you = %i', $dip['me'], $dip['you']);
|
||||
}
|
||||
|
||||
//개전국 로그
|
||||
foreach ($db->query('SELECT me, you FROM diplomacy WHERE state = 1 AND term <= 1 AND me < you') as $dip) {
|
||||
$nation1 = getNationStaticInfo($dip['me']);
|
||||
$name1 = $nation1['name'];
|
||||
$nation2 = getNationStaticInfo($dip['you']);
|
||||
$name2 = $nation2['name'];
|
||||
|
||||
$josaYi = JosaUtil::pick($name2, '이');
|
||||
$josaWa = JosaUtil::pick($name1, '와');
|
||||
$globalLogger->pushGlobalHistoryLog("<R><b>【개전】</b></><D><b>$name1</b></>{$josaWa} <D><b>$name2</b></>{$josaYi} <R>전쟁</>을 시작합니다.");
|
||||
}
|
||||
//휴전국 로그
|
||||
$stopWarList = [];
|
||||
foreach ($db->queryAllLists('SELECT me,you FROM diplomacy WHERE state=0 AND term <= 1 ORDER BY me desc, you desc') as [$me, $you]) {
|
||||
if ($me < $you) {
|
||||
$key = "{$me}_{$you}";
|
||||
} else {
|
||||
$key = "{$you}_{$me}";
|
||||
}
|
||||
if (!key_exists($key, $stopWarList)) {
|
||||
$stopWarList[$key] = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
//양측 기간 모두 0이 되는 상황이면 휴전
|
||||
$nation1 = getNationStaticInfo($me);
|
||||
$name1 = $nation1['name'];
|
||||
$nation2 = getNationStaticInfo($you);
|
||||
$name2 = $nation2['name'];
|
||||
|
||||
$josaWa = JosaUtil::pick($name1, '와');
|
||||
$josaYi = JosaUtil::pick($name2, '이');
|
||||
|
||||
$globalLogger->pushGlobalHistoryLog("<R><b>【휴전】</b></><D><b>$name1</b></>{$josaWa} <D><b>$name2</b></>{$josaYi} <S>휴전</>합니다.");
|
||||
$db->update('diplomacy', [
|
||||
'state' => 2,
|
||||
'term' => 0,
|
||||
], '(me=%i AND you=%i) OR (you=%i AND me=%i)', $me, $you, $me, $you);
|
||||
}
|
||||
|
||||
$globalLogger->flush();
|
||||
|
||||
//사상자 초기화, 외교 기한-1
|
||||
$db->update('diplomacy', [
|
||||
'dead' => $db->sqleval('if(state!=0, 0, dead)'),
|
||||
'term' => $db->sqleval('greatest(0, term-1)'),
|
||||
], true);
|
||||
//불가침 끝나면 통상으로
|
||||
$db->update('diplomacy', [
|
||||
'state' => 2,
|
||||
], 'state = 7 AND term = 0');
|
||||
//선포 끝나면 교전으로
|
||||
$db->update('diplomacy', [
|
||||
'state' => 0,
|
||||
'term' => 6,
|
||||
], 'state = 1 AND term = 0');
|
||||
|
||||
//초반이후 방랑군 자동 해체
|
||||
if ($admin['year'] >= $admin['startyear'] + 2) {
|
||||
checkWander();
|
||||
}
|
||||
// 작위 업데이트
|
||||
updateNationState();
|
||||
updateGeneralNumber();
|
||||
refreshNationStaticInfo();
|
||||
// 천통여부 검사
|
||||
checkEmperior();
|
||||
//토너먼트 개시
|
||||
triggerTournament();
|
||||
// 시스템 거래건 등록
|
||||
registerAuction();
|
||||
//전방설정
|
||||
foreach (getAllNationStaticInfo() as $nation) {
|
||||
if ($nation['level'] <= 0) {
|
||||
continue;
|
||||
}
|
||||
SetNationFront($nation['nation']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function checkWander()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month']);
|
||||
|
||||
$wanderers = $db->queryFirstColumn('SELECT general.`no` FROM general LEFT JOIN nation ON general.nation = nation.nation WHERE nation.`level` = 0 AND general.`officer_level` = 12');
|
||||
|
||||
foreach (General::createGeneralObjListFromDB($wanderers) as $wanderer) {
|
||||
$wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin);
|
||||
if ($wanderCmd->hasFullConditionMet()) {
|
||||
$logger = $wanderer->getLogger();
|
||||
$logger->pushGeneralActionLog('초반 제한후 방랑군은 자동 해산됩니다.', ActionLogger::PLAIN);
|
||||
$wanderCmd->run();
|
||||
$wanderCmd->setNextAvailable();
|
||||
}
|
||||
}
|
||||
|
||||
if ($wanderers) {
|
||||
refreshNationStaticInfo();
|
||||
}
|
||||
}
|
||||
|
||||
function updateNationState()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$history = array();
|
||||
$admin = $gameStor->getValues(['killturn', 'year', 'month', 'fiction', 'startyear', 'show_img_level', 'turnterm', 'turntime']);
|
||||
|
||||
$assemblerCnts = [];
|
||||
foreach ($db->queryAllLists('SELECT nation,count(no) FROM general WHERE npc = 5 GROUP BY nation') as [$nationID, $assemblerCnt]) {
|
||||
$assemblerCnts[$nationID] = $assemblerCnt;
|
||||
};
|
||||
|
||||
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
|
||||
//TODO: level이 진관수이소중대특 체계를 벗어날 수 있음
|
||||
$citycount = $db->queryFirstField('SELECT count(*) FROM city WHERE nation=%i AND level>=4', $nation['nation']);
|
||||
|
||||
if ($citycount == 0) {
|
||||
$nationlevel = 0; // 방랑군
|
||||
} elseif ($citycount == 1) {
|
||||
$nationlevel = 1; // 호족
|
||||
} elseif ($citycount <= 4) {
|
||||
$nationlevel = 2; // 군벌
|
||||
} elseif ($citycount <= 7) {
|
||||
$nationlevel = 3; // 주자사
|
||||
} elseif ($citycount <= 10) {
|
||||
$nationlevel = 4; // 주목
|
||||
} elseif ($citycount <= 15) {
|
||||
$nationlevel = 5; // 공
|
||||
} elseif ($citycount <= 20) {
|
||||
$nationlevel = 6; // 왕
|
||||
} else {
|
||||
$nationlevel = 7; // 황제
|
||||
}
|
||||
|
||||
if ($nationlevel > $nation['level']) {
|
||||
$levelDiff = $nationlevel - $nation['level'];
|
||||
$oldLevel = $nation['level'];
|
||||
$nation['level'] = $nationlevel;
|
||||
|
||||
$updateVals = [
|
||||
'level' => $nationlevel,
|
||||
'gold' => $db->sqleval('gold + %i', $nationlevel * 1000),
|
||||
'rice' => $db->sqleval('rice + %i', $nationlevel * 1000),
|
||||
];
|
||||
|
||||
switch ($nationlevel) {
|
||||
case 7:
|
||||
$josaUl = JosaUtil::pick(getNationLevel($nationlevel), '을');
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭하였습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭"]);
|
||||
$auxVal = Json::decode($nation['aux']);
|
||||
$auxVal['can_국기변경'] = 1;
|
||||
$auxVal['can_국호변경'] = 1;
|
||||
$updateVals['aux'] = Json::encode($auxVal);
|
||||
break;
|
||||
case 6:
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극하였습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극"]);
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
case 3:
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명되었습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명됨"]);
|
||||
break;
|
||||
case 2:
|
||||
$history[] = "<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 독립하여 <Y>" . getNationLevel($nationlevel) . "</>로 나섰습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}년 {$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>로 나서다"]);
|
||||
break;
|
||||
}
|
||||
|
||||
$db->update('nation', $updateVals, 'nation=%i', $nation['nation']);
|
||||
|
||||
$turnRows = [];
|
||||
foreach (Util::range(getNationChiefLevel($nation['level']), 12) as $chiefLevel) {
|
||||
foreach (Util::range(GameConst::$maxChiefTurn) as $turnIdx) {
|
||||
$turnRows[] = [
|
||||
'nation_id' => $nation['nation'],
|
||||
'officer_level' => $chiefLevel,
|
||||
'turn_idx' => $turnIdx,
|
||||
'action' => '휴식',
|
||||
'arg' => null,
|
||||
'brief' => '휴식'
|
||||
];
|
||||
}
|
||||
}
|
||||
$db->insertIgnore('nation_turn', $turnRows);
|
||||
|
||||
if ($levelDiff) {
|
||||
//유니크 아이템 하나 돌리자
|
||||
$targetKillTurn = $admin['killturn'];
|
||||
$targetKillTurn -= 24 * 60 / $admin['turnterm'];
|
||||
$nationGenIDList = $db->queryFirstColumn(
|
||||
'SELECT no FROM general WHERE nation = %i AND killturn >= %i AND npc < 2',
|
||||
$nation['nation'],
|
||||
$targetKillTurn
|
||||
);
|
||||
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2);
|
||||
$chiefID = null;
|
||||
|
||||
$uniqueLotteryWeightList = [];
|
||||
|
||||
[$startYear, $year] = $gameStor->getValuesAsArray(['startyear', 'year']);
|
||||
$relYear = $year - $startYear;
|
||||
$maxTrialCountByYear = 1;
|
||||
foreach (GameConst::$maxUniqueItemLimit as $tmpVals) {
|
||||
[$targetYear, $targetTrialCnt] = $tmpVals;
|
||||
if ($relYear < $targetYear) {
|
||||
break;
|
||||
}
|
||||
$maxTrialCountByYear = $targetTrialCnt;
|
||||
}
|
||||
foreach ($nationGenList as $nationGen) {
|
||||
if ($nationGen->getVar('officer_level') == 12) {
|
||||
$chiefID = $nationGen->getID();
|
||||
}
|
||||
$trialCnt = min($maxTrialCountByYear, count(GameConst::$allItems));
|
||||
|
||||
foreach ($nationGen->getItems() as $item) {
|
||||
if (!$item->isBuyable()) {
|
||||
$trialCnt -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ($trialCnt <= 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$score = $nationGen->getVar('belong') + 5;
|
||||
|
||||
if ($nationGen->getVar('officer_level') == 12) {
|
||||
$score += 100; //NOTE: 꼬우면 군주하세요.
|
||||
} else if ($nationGen->getVar('officer_level') == 11) {
|
||||
$score += 50;
|
||||
} else if ($nationGen->getVar('officer_level') > 4) {
|
||||
$score += 35;
|
||||
}
|
||||
|
||||
$score *= $trialCnt;
|
||||
|
||||
$uniqueLotteryWeightList[$nationGen->getID()] = [$nationGen, $score];
|
||||
}
|
||||
|
||||
foreach (Util::range($levelDiff) as $idx) {
|
||||
if (!$uniqueLotteryWeightList) {
|
||||
break;
|
||||
}
|
||||
|
||||
/** @var General */
|
||||
$winnerObj = Util::choiceRandomUsingWeightPair($uniqueLotteryWeightList);
|
||||
unset($uniqueLotteryWeightList[$winnerObj->getID()]);
|
||||
giveRandomUniqueItem($winnerObj, '작위보상');
|
||||
$winnerObj->applyDB($db);
|
||||
}
|
||||
|
||||
if ($chiefID) {
|
||||
$chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], 2);
|
||||
$chiefObj->increaseInheritancePoint('unifier', 250 * $levelDiff);
|
||||
$chiefObj->applyDB($db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$assemblerCnt = $assemblerCnts[$nation['nation']] ?? 0;
|
||||
$maxAssemblerCnt = [
|
||||
1 => 0,
|
||||
2 => 1,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 6,
|
||||
6 => 7,
|
||||
7 => 9
|
||||
][$nationlevel] ?? 0;
|
||||
|
||||
if ($assemblerCnt < $maxAssemblerCnt) {
|
||||
$lastAssemblerID = $gameStor->assembler_id ?? 0;
|
||||
|
||||
while ($assemblerCnt < $maxAssemblerCnt) {
|
||||
$lastAssemblerID += 1;
|
||||
$npcObj = new Scenario\GeneralBuilder(
|
||||
sprintf('부대장%4d', $lastAssemblerID),
|
||||
false,
|
||||
null,
|
||||
$nation['nation']
|
||||
);
|
||||
$npcObj->setAffinity(999)->setStat(10, 10, 10)
|
||||
->setSpecialSingle('척사')->setEgo('che_은둔')
|
||||
->setKillturn(70)->setGoldRice(0, 0)
|
||||
->setNPCType(5)->fillRemainSpecAsZero($admin);
|
||||
$npcObj->build($admin);
|
||||
$npcID = $npcObj->getGeneralID();
|
||||
|
||||
$db->insert('troop', [
|
||||
'troop_leader' => $npcID,
|
||||
'name' => $npcObj->getGeneralName(),
|
||||
'nation' => $nation['nation'],
|
||||
]);
|
||||
$db->update('general', [
|
||||
'troop' => $npcID
|
||||
], 'no=%i', $npcID);
|
||||
|
||||
$cmd = buildGeneralCommandClass('che_집합', General::createGeneralObjFromDB($npcID), $admin);
|
||||
_setGeneralCommand($cmd, iterator_to_array(Util::range(GameConst::$maxTurn)));
|
||||
$assemblerCnt += 1;
|
||||
$gameStor->assembler_id = $lastAssemblerID;
|
||||
}
|
||||
}
|
||||
}
|
||||
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
|
||||
}
|
||||
|
||||
function checkStatistic()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month']);
|
||||
|
||||
$nationHists = [];
|
||||
$specialHists = [];
|
||||
$personalHists = [];
|
||||
$specialHists2 = [];
|
||||
$crewtypeHists = [];
|
||||
|
||||
$etc = '';
|
||||
|
||||
$auxData = [
|
||||
'generals' => [],
|
||||
'nations' => [],
|
||||
];
|
||||
|
||||
$avgGeneral = $db->queryFirstRow(
|
||||
'SELECT avg(gold) as avggold, avg(rice) as avgrice, avg(dex1+dex2+dex3+dex4) as avgdex,
|
||||
max(dex1+dex2+dex3+dex4) as maxdex, avg(experience+dedication) as avgexpded, max(experience+dedication) as maxexpded
|
||||
FROM general'
|
||||
);
|
||||
$auxData['generals']['avg'] = $avgGeneral;
|
||||
|
||||
$avgGeneral['avggold'] = Util::round($avgGeneral['avggold']);
|
||||
$avgGeneral['avgrice'] = Util::round($avgGeneral['avgrice']);
|
||||
$avgGeneral['avgdex'] = Util::round($avgGeneral['avgdex']);
|
||||
$avgGeneral['avgexpded'] = Util::round($avgGeneral['avgexpded']);
|
||||
$etc .= "평균 금/쌀 ({$avgGeneral['avggold']}/{$avgGeneral['avgrice']}), 평균/최고 숙련({$avgGeneral['avgdex']}/{$avgGeneral['maxdex']}), 평균/최고 경험공헌({$avgGeneral['avgexpded']}/{$avgGeneral['maxexpded']}), ";
|
||||
|
||||
$avgNation = $db->queryFirstRow(
|
||||
'SELECT min(tech) as mintech, max(tech) as maxtech, avg(tech) as avgtech,
|
||||
min(power) as minpower, max(power) as maxpower, avg(power) as avgpower from nation where level>0'
|
||||
);
|
||||
$auxData['nations']['avg'] = $avgNation;
|
||||
|
||||
$avgNation['mintech'] = floor($avgNation['mintech']);
|
||||
$avgNation['maxtech'] = floor($avgNation['maxtech']);
|
||||
$avgNation['avgtech'] = Util::round($avgNation['avgtech']);
|
||||
$avgNation['avgpower'] = Util::round($avgNation['avgpower']);
|
||||
$etc .= "최저/평균/최고 기술({$avgNation['mintech']}/{$avgNation['avgtech']}/{$avgNation['maxtech']}), ";
|
||||
$etc .= "최저/평균/최고 국력({$avgNation['minpower']}/{$avgNation['avgpower']}/{$avgNation['maxpower']}), ";
|
||||
|
||||
$nationName = '';
|
||||
$powerHist = '';
|
||||
|
||||
$nations = Util::convertArrayToDict(
|
||||
$db->query(
|
||||
'SELECT nation,name,type,power,gennum,gold+rice as goldrice from nation where level>0 order by power desc',
|
||||
'nation'
|
||||
),
|
||||
'nation'
|
||||
);
|
||||
$nationCount = count($nations);
|
||||
|
||||
$nationGeneralInfos = Util::convertArrayToDict(
|
||||
$db->query(
|
||||
'SELECT nation, sum(leadership+strength+intel) as abil,sum(gold+rice) as goldrice,
|
||||
sum(dex1+dex2+dex3+dex4) as dex,sum(experience+dedication) as expded
|
||||
from general GROUP BY nation'
|
||||
),
|
||||
'nation'
|
||||
);
|
||||
|
||||
$nationCityInfos = Util::convertArrayToDict(
|
||||
$db->query('SELECT nation, count(*) as cnt, sum(pop) as pop,sum(pop_max) as pop_max from city GROUP BY nation'),
|
||||
'nation'
|
||||
);
|
||||
|
||||
foreach ($nations as $nationNo => &$nation) {
|
||||
$general = $nationGeneralInfos[$nationNo];
|
||||
$city = $nationCityInfos[$nationNo];
|
||||
|
||||
$nation['generalInfo'] = $general;
|
||||
$nation['cityInfo'] = $city;
|
||||
|
||||
$nationName .= $nation['name'] . '(' . getNationType($nation['type']) . '), ';
|
||||
$powerHist .= "{$nation['name']}({$nation['power']}/{$nation['gennum']}/{$city['cnt']}/{$city['pop']}/{$city['pop_max']}/{$nation['goldrice']}/{$general['goldrice']}/{$general['abil']}/{$general['dex']}/{$general['expded']}), ";
|
||||
|
||||
if (!isset($nationHists[$nation['type']])) {
|
||||
$nationHists[$nation['type']] = 0;
|
||||
}
|
||||
$nationHists[$nation['type']]++;
|
||||
}
|
||||
unset($nation);
|
||||
|
||||
$auxData['nations']['all'] = $nations;
|
||||
|
||||
$nationHist = '';
|
||||
foreach (GameConst::$availableNationType as $nationType) {
|
||||
if (!Util::array_get($nationHists[$nationType])) {
|
||||
$nationHists[$nationType] = '-';
|
||||
}
|
||||
$nationHist .= getNationType($nationType) . "({$nationHists[$nationType]}), ";
|
||||
}
|
||||
|
||||
$generals = $db->query('SELECT `no`,npc,personal,special,special2,crewtype FROM general');
|
||||
|
||||
$genCount = 0;
|
||||
$npcCount = 0;
|
||||
$generalCount = count($generals);
|
||||
|
||||
foreach ($generals as $general) {
|
||||
if (!isset($personalHists[$general['personal']])) {
|
||||
$personalHists[$general['personal']] = 0;
|
||||
}
|
||||
|
||||
if (!isset($specialHists[$general['special']])) {
|
||||
$specialHists[$general['special']] = 0;
|
||||
}
|
||||
|
||||
if (!isset($specialHists2[$general['special2']])) {
|
||||
$specialHists2[$general['special2']] = 0;
|
||||
}
|
||||
|
||||
if ($general['npc'] < 2) {
|
||||
$genCount += 1;
|
||||
} else {
|
||||
$npcCount += 1;
|
||||
}
|
||||
|
||||
$personalHists[$general['personal']]++;
|
||||
$specialHists[$general['special']]++;
|
||||
$specialHists2[$general['special2']]++;
|
||||
}
|
||||
|
||||
foreach ($db->queryAllLists(
|
||||
'SELECT crewtype, count(crewtype) AS cnt FROM general WHERE recent_war != NULL GROUP BY crewtype'
|
||||
) as [$crewtype, $cnt]) {
|
||||
$crewtypeHists[$crewtype] = $cnt;
|
||||
}
|
||||
|
||||
$auxData['generals']['hists'] = [
|
||||
'personal' => $personalHists,
|
||||
'special' => $specialHists,
|
||||
'special2' => $specialHists2,
|
||||
'crewtype' => $crewtypeHists,
|
||||
'userCnt' => $genCount,
|
||||
'npcCnt' => $npcCount,
|
||||
];
|
||||
|
||||
$generalCountStr = "{$generalCount}({$genCount}+{$npcCount})";
|
||||
|
||||
$personalHistStr = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return getGenChar($histKey) . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($personalHists)));
|
||||
|
||||
$specialHistsStr = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return getGeneralSpecialDomesticName($histKey) . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($specialHists)));
|
||||
|
||||
$specialHists2Str = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return getGeneralSpecialWarName($histKey) . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($specialHists2)));
|
||||
|
||||
$specialHistsAllStr = "$specialHistsStr // $specialHists2Str";
|
||||
|
||||
$crewtypeHistsStr = join(', ', array_map(function ($histPair) {
|
||||
[$histKey, $cnt] = $histPair;
|
||||
return GameUnitConst::byID($histKey)->getShortName() . '(' . $cnt . ')';
|
||||
}, Util::convertDictToArray($crewtypeHists)));
|
||||
|
||||
$db->insert('statistic', [
|
||||
'year' => $admin['year'],
|
||||
'month' => $admin['month'],
|
||||
'nation_count' => $nationCount,
|
||||
'nation_name' => $nationName,
|
||||
'nation_hist' => $nationHist,
|
||||
'gen_count' => $generalCountStr,
|
||||
'personal_hist' => $personalHistStr,
|
||||
'special_hist' => $specialHistsAllStr,
|
||||
'power_hist' => $powerHist,
|
||||
'crewtype' => $crewtypeHistsStr,
|
||||
'etc' => $etc,
|
||||
'aux' => Json::encode($auxData)
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
function convForOldGeneral(array $general, int $year, int $month)
|
||||
{
|
||||
$general['history'] = getGeneralHistoryLogAll($general['no']);
|
||||
return [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'general_no' => $general['no'],
|
||||
'owner' => $general['owner'],
|
||||
'name' => $general['name'],
|
||||
'last_yearmonth' => $year * 100 + $month,
|
||||
'turntime' => $general['turntime'],
|
||||
'data' => Json::encode($general)
|
||||
];
|
||||
}
|
||||
|
||||
function storeOldGeneral(int $no, int $year, int $month)
|
||||
{
|
||||
$db = DB::db();
|
||||
$general = $db->queryFirstRow('SELECT * FROM general WHERE `no` = %i', $no);
|
||||
if (!$general) {
|
||||
return;
|
||||
}
|
||||
$data = convForOldGeneral($general, $year, $month);
|
||||
$db->insertUpdate(
|
||||
'ng_old_generals',
|
||||
$data,
|
||||
$data
|
||||
);
|
||||
}
|
||||
|
||||
function storeOldGenerals(int $nation, int $year, int $month)
|
||||
{
|
||||
$db = DB::db();
|
||||
foreach ($db->query('SELECT * FROM general WHERE nation = %i', $nation) as $general) {
|
||||
$data = convForOldGeneral($general, $year, $month);
|
||||
$db->insertUpdate(
|
||||
'ng_old_generals',
|
||||
$data,
|
||||
$data
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function checkEmperior()
|
||||
{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'conlimit']);
|
||||
if ($admin['isunited'] != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
$remainNations = $db->queryFirstColumn('SELECT nation FROM nation WHERE level > 0 LIMIT 2');
|
||||
|
||||
if (!$remainNations || count($remainNations) != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
$nationID = $remainNations[0];
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
$cityCnt = $db->queryFirstField('SELECT count(city) FROM city WHERE nation=%i', $nationID);
|
||||
if (!$cityCnt) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($cityCnt != count(CityConst::all())) {
|
||||
return;
|
||||
}
|
||||
|
||||
checkStatistic();
|
||||
|
||||
$nation = $db->queryFirstRow('SELECT * FROM nation WHERE nation=%i', $nationID);
|
||||
$nationName = $nation['name'];
|
||||
|
||||
$josaYi = JosaUtil::pick($nationName, '이');
|
||||
|
||||
$nationLogger = new ActionLogger(0, $nationID, $admin['year'], $admin['month']);
|
||||
$nationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일");
|
||||
|
||||
foreach (General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj) {
|
||||
if ($genObj->getNationID() == $nationID) {
|
||||
if ($genObj->getVar('officer_level') > 4) {
|
||||
$genObj->increaseInheritancePoint('unifier', 2000);
|
||||
};
|
||||
}
|
||||
$genObj->mergeTotalInheritancePoint();
|
||||
}
|
||||
|
||||
$gameStor->isunited = 2;
|
||||
$gameStor->conlimit = $gameStor->conlimit * 100;
|
||||
|
||||
foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) {
|
||||
CheckHall($hallGeneralNo);
|
||||
}
|
||||
|
||||
[$totalPop, $totalMaxPop] = $db->queryFirstList('SELECT SUM(pop), SUM(pop_max) FROM city');
|
||||
$pop = "{$totalPop} / {$totalMaxPop}";
|
||||
$poprate = round($totalPop / $totalMaxPop * 100, 2) . " %";
|
||||
|
||||
$chiefs = Util::convertArrayToDict(
|
||||
$db->query(
|
||||
'SELECT no,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5',
|
||||
$nationID
|
||||
),
|
||||
'officer_level'
|
||||
);
|
||||
|
||||
$nationGenerals = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=%i', $nationID);
|
||||
$nation['generals'] = $nationGenerals;
|
||||
|
||||
$tigers = $db->query(
|
||||
'SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "killnum" AND value > 0 ORDER BY value DESC LIMIT 5',
|
||||
$nationID
|
||||
); // 오호장군
|
||||
|
||||
$tigerstr = join(', ', array_map(function ($arr) {
|
||||
$number = number_format($arr['value']);
|
||||
return "{$arr['name']}【{$number}】";
|
||||
}, $tigers));
|
||||
|
||||
$eagles = $db->query(
|
||||
'SELECT value, name
|
||||
FROM rank_data LEFT JOIN general ON rank_data.general_id = general.no
|
||||
WHERE rank_data.nation_id = %i AND rank_data.type = "firenum" AND value > 0 ORDER BY value DESC LIMIT 7',
|
||||
$nationID
|
||||
); // 건안칠자
|
||||
|
||||
$eaglestr = join(', ', array_map(function ($arr) {
|
||||
$number = number_format($arr['value']);
|
||||
return "{$arr['name']}【{$number}】";
|
||||
}, $eagles));
|
||||
|
||||
$rawGeneralList = $db->query('SELECT no, name, npc, owner FROM general WHERE nation=%i ORDER BY dedication DESC', $nationID);
|
||||
foreach ($rawGeneralList as $rawGeneral) {
|
||||
$generalLogger = new ActionLogger($rawGeneral['no'], $nationID, $admin['year'], $admin['month']);
|
||||
$generalLogger->pushGeneralActionLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일하였습니다.", ActionLogger::YEAR_MONTH);
|
||||
$generalLogger->flush();
|
||||
}
|
||||
|
||||
$gen = join(', ', array_column($rawGeneralList, 'name'));
|
||||
|
||||
$stat = $db->queryFirstRow('SELECT max(nation_count) as nc, max(gen_count) as gc FROM statistic');
|
||||
$genCnt = $db->queryFirstField('SELECT count(*) FROM general');
|
||||
|
||||
$statNC = "1 / {$stat['nc']}";
|
||||
$statGC = "{$genCnt} / {$stat['gc']}";
|
||||
$statNation = $db->queryFirstRow('SELECT nation_count,nation_name,nation_hist from statistic where nation_count=%i LIMIT 1', $stat['nc']);
|
||||
$statGeneral = $db->queryFirstRow('SELECT gen_count,personal_hist,special_hist,aux from statistic order by no desc LIMIT 1');
|
||||
|
||||
$nation = $nation;
|
||||
$nation['generals'] = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=%i', $nation['nation']);
|
||||
$nation['aux'] = Json::decode($nation['aux']);
|
||||
$nation['msg'] = $nationStor->notice;
|
||||
$nation['scout_msg'] = $nationStor->scout_msg;
|
||||
$nation['aux'] += $nationStor->max_power;
|
||||
$nation['history'] = getNationHistoryLogAll($nation['nation']);
|
||||
|
||||
storeOldGenerals(0, $admin['year'], $admin['month']);
|
||||
storeOldGenerals($nation['nation'], $admin['year'], $admin['month']);
|
||||
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => $nation['nation'],
|
||||
'data' => Json::encode($nation)
|
||||
]);
|
||||
|
||||
$noNationGeneral = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=0');
|
||||
$db->insert('ng_old_nations', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation' => 0,
|
||||
'data' => Json::encode([
|
||||
'nation' => 0,
|
||||
'name' => '재야',
|
||||
'generals' => $noNationGeneral
|
||||
])
|
||||
]);
|
||||
|
||||
$nationHistory = getNationHistoryLogAll($nation['nation']);
|
||||
|
||||
$serverCnt = $db->queryFirstField('SELECT count(*) FROM ng_games');
|
||||
$serverName = UniqueConst::$serverName;
|
||||
|
||||
$db->update('ng_games', [
|
||||
'winner_nation' => $nation['nation']
|
||||
], 'server_id=%s', UniqueConst::$serverID);
|
||||
|
||||
$db->insert('emperior', [
|
||||
'phase' => $serverName . $serverCnt . '기',
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'nation_count' => $statNC,
|
||||
'nation_name' => $statNation['nation_name'],
|
||||
'nation_hist' => $statNation['nation_hist'],
|
||||
'gen_count' => $statGC,
|
||||
'personal_hist' => $statGeneral['personal_hist'],
|
||||
'special_hist' => $statGeneral['special_hist'],
|
||||
'name' => $nation['name'],
|
||||
'type' => $nation['type'],
|
||||
'color' => $nation['color'],
|
||||
'year' => $admin['year'],
|
||||
'month' => $admin['month'],
|
||||
'power' => $nation['power'],
|
||||
'gennum' => $nation['gennum'],
|
||||
'citynum' => $cityCnt,
|
||||
'pop' => $pop,
|
||||
'poprate' => $poprate,
|
||||
'gold' => $nation['gold'],
|
||||
'rice' => $nation['rice'],
|
||||
'l12name' => $chiefs[12]['name'],
|
||||
'l12pic' => $chiefs[12]['picture'],
|
||||
'l11name' => $chiefs[11]['name'],
|
||||
'l11pic' => $chiefs[11]['picture'],
|
||||
'l10name' => $chiefs[10]['name'],
|
||||
'l10pic' => $chiefs[10]['picture'],
|
||||
'l9name' => $chiefs[9]['name'],
|
||||
'l9pic' => $chiefs[9]['picture'],
|
||||
'l8name' => $chiefs[8]['name'],
|
||||
'l8pic' => $chiefs[8]['picture'],
|
||||
'l7name' => $chiefs[7]['name'],
|
||||
'l7pic' => $chiefs[7]['picture'],
|
||||
'l6name' => $chiefs[6]['name'],
|
||||
'l6pic' => $chiefs[6]['picture'],
|
||||
'l5name' => $chiefs[5]['name'],
|
||||
'l5pic' => $chiefs[5]['picture'],
|
||||
'tiger' => $tigerstr,
|
||||
'eagle' => $eaglestr,
|
||||
'gen' => $gen,
|
||||
'history' => JSON::encode($nationHistory),
|
||||
'aux' => $statGeneral['aux']
|
||||
]);
|
||||
|
||||
$history = ["<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【통일】</b></><D><b>{$nation['name']}</b></>{$josaYi} 전토를 통일하였습니다."];
|
||||
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
|
||||
|
||||
//연감 월결산
|
||||
LogHistory();
|
||||
}
|
||||
|
||||
function resetInheritanceUser(int $userID, bool $isRebirth = false): float
|
||||
{
|
||||
$rebirthDegraded = [
|
||||
'dex' => 0.5,
|
||||
];
|
||||
|
||||
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
|
||||
$totalPoint = 0;
|
||||
$allPoints = $inheritStor->getAll();
|
||||
if (!$allPoints || count($allPoints) == 0) {
|
||||
//비었으므로 리셋 안함
|
||||
return 0;
|
||||
}
|
||||
if (count($allPoints) == 1 && key_exists('previous', $allPoints)) {
|
||||
//이미 리셋되었으므로 리셋 안함
|
||||
return $allPoints['previous'][0];
|
||||
}
|
||||
|
||||
$userLogger = new UserLogger($userID);
|
||||
|
||||
$previousPoint = ($allPoints['previous'] ?? [0, 0])[0];
|
||||
|
||||
foreach ($allPoints as $key => [$value,]) {
|
||||
if ($isRebirth && key_exists($key, $rebirthDegraded)) {
|
||||
$value *= $rebirthDegraded[$key];
|
||||
}
|
||||
$keyText = General::INHERITANCE_KEY[$key][2];
|
||||
$userLogger->push("{$keyText} 포인트 {$value} 증가", "inheritPoint");
|
||||
$totalPoint += $value;
|
||||
}
|
||||
$totalPoint = Util::toInt($totalPoint);
|
||||
$userLogger->push("포인트 {$previousPoint} => {$totalPoint}", "inheritPoint");
|
||||
$userLogger->flush();
|
||||
|
||||
$inheritStor->resetValues();
|
||||
$inheritStor->setValue('previous', [$totalPoint, null]);
|
||||
return $totalPoint;
|
||||
}
|
||||
|
||||
function updateMaxDomesticCritical(General $general, $score)
|
||||
{
|
||||
$maxDomesticCritical = $general->getAuxVar('max_domestic_critical') ?? 0;
|
||||
$maxDomesticCritical += $score / 2;
|
||||
$general->setAuxVar('max_domestic_critical', $maxDomesticCritical);
|
||||
|
||||
$oldMaxDomesticCritical = $general->getInheritancePoint('max_domestic_critical');
|
||||
if ($maxDomesticCritical > $oldMaxDomesticCritical) {
|
||||
$general->setInheritancePoint('max_domestic_critical', $maxDomesticCritical);
|
||||
}
|
||||
}
|
||||
|
||||
+14
-25
@@ -77,12 +77,6 @@ function pushProcessLog($log) {
|
||||
pushRawFileLog(__DIR__."/logs/".UniqueConst::$serverID."/_{$date}_processlog.txt", $log);
|
||||
}
|
||||
|
||||
|
||||
function pushStepLog($log) {
|
||||
$date = date('Y_m_d');
|
||||
pushRawFileLog(__DIR__."/logs/".UniqueConst::$serverID."/_{$date}_steplog.txt", $log);
|
||||
}
|
||||
|
||||
function pushLockLog($log) {
|
||||
$date = date('Y_m_d');
|
||||
pushRawFileLog(__DIR__."/logs/".UniqueConst::$serverID."/_{$date}_locklog.txt", $log);
|
||||
@@ -105,15 +99,15 @@ function formatHistoryToHTML(array $history, ?string $type=null):string{
|
||||
$result = [];
|
||||
if($type){
|
||||
foreach($history as $seq=>$item){
|
||||
$result[] = "<div class='log_{$type}' id='log_{$type}_{$seq}' data-seq='{$seq}'>".ConvertLog($item).'</div>';
|
||||
$result[] = "<div class='log_{$type}' id='log_{$type}_{$seq}' data-seq='{$seq}'>".ConvertLog($item).'</div>';
|
||||
}
|
||||
}
|
||||
else{
|
||||
foreach($history as $seq=>$item){
|
||||
$result[] = '<div>'.ConvertLog($item).'</div>';
|
||||
$result[] = '<div>'.ConvertLog($item).'</div>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return join('', $result);
|
||||
}
|
||||
|
||||
@@ -242,7 +236,7 @@ function pushGeneralHistoryLog(int $generalID, ?array $history, $year=null, $mon
|
||||
return;
|
||||
}
|
||||
$db = DB::db();
|
||||
|
||||
|
||||
if($year === null || $month === null){
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']);
|
||||
@@ -278,7 +272,7 @@ function pushNationHistoryLog(int $nationID, ?array $history, ?int $year=null, ?
|
||||
return;
|
||||
}
|
||||
$db = DB::db();
|
||||
|
||||
|
||||
if($year === null || $month === null){
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']);
|
||||
@@ -304,7 +298,7 @@ function pushGlobalHistoryLog(?array $history, $year=null, $month=null) {
|
||||
return;
|
||||
}
|
||||
$db = DB::db();
|
||||
|
||||
|
||||
if($year === null || $month === null){
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']);
|
||||
@@ -325,8 +319,8 @@ function getGlobalHistoryLogWithDate(int $year, int $month):array {
|
||||
$db = DB::db();
|
||||
|
||||
$texts = $db->queryFirstColumn(
|
||||
'SELECT `text` from world_history where nation_id = 0 AND year = %i and month = %i order by id desc',
|
||||
$year,
|
||||
'SELECT `text` from world_history where nation_id = 0 AND year = %i and month = %i order by id desc',
|
||||
$year,
|
||||
$month
|
||||
);
|
||||
|
||||
@@ -342,7 +336,7 @@ function pushGlobalActionLog(?array $history, ?int $year=null, ?int $month=null)
|
||||
return;
|
||||
}
|
||||
$db = DB::db();
|
||||
|
||||
|
||||
if($year === null || $month === null){
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
list($year, $month) = $gameStor->getValuesAsArray(['year', 'month']);
|
||||
@@ -366,8 +360,8 @@ function getGlobalActionLogWithDate(int $year, int $month):array {
|
||||
$db = DB::db();
|
||||
|
||||
$texts = $db->queryFirstColumn(
|
||||
'SELECT `text` from general_record where general_id = 0 AND log_type = "history" AND year = %i and month = %i order by id desc',
|
||||
$year,
|
||||
'SELECT `text` from general_record where general_id = 0 AND log_type = "history" AND year = %i and month = %i order by id desc',
|
||||
$year,
|
||||
$month
|
||||
);
|
||||
|
||||
@@ -378,8 +372,6 @@ function getGlobalActionLogWithDate(int $year, int $month):array {
|
||||
}
|
||||
|
||||
function LogHistory($isFirst=0) {
|
||||
if(STEP_LOG) pushStepLog(TimeUtil::now().', LogHistory Start');
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$obj = $gameStor->getValues(['startyear', 'year', 'month']);
|
||||
@@ -401,16 +393,16 @@ function LogHistory($isFirst=0) {
|
||||
if($map['month'] == 0){
|
||||
$map['month'] = 12;
|
||||
$map['year'] -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$year = $map['year'];
|
||||
$month = $map['month'];
|
||||
|
||||
|
||||
|
||||
$globalHistory = getGlobalHistoryLogWithDate($year, $month);
|
||||
$globalAction = getGlobalActionLogWithDate($year, $month);
|
||||
|
||||
|
||||
$nations = getAllNationStaticInfo();
|
||||
$nations[0] = getNationStaticInfo(0);
|
||||
|
||||
@@ -426,8 +418,6 @@ function LogHistory($isFirst=0) {
|
||||
return -($lhs['power']<=>$rhs['power']);
|
||||
});
|
||||
|
||||
if(STEP_LOG) pushStepLog(TimeUtil::now().', contents collected');
|
||||
|
||||
$db->insert('ng_history', [
|
||||
'server_id' => UniqueConst::$serverID,
|
||||
'year' => $year,
|
||||
@@ -438,6 +428,5 @@ function LogHistory($isFirst=0) {
|
||||
'nations' => Json::encode($nations),
|
||||
]);
|
||||
|
||||
if(STEP_LOG) pushStepLog(TimeUtil::now().', LogHistory Finish');
|
||||
return true;
|
||||
}
|
||||
|
||||
+274
-270
@@ -1,270 +1,274 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
|
||||
/**
|
||||
* 템플릿 생성과 관련된 함수들을 모아두는 파일
|
||||
*
|
||||
* NOTE: 아직 converter와 명확한 구분이 되어있지 않음.
|
||||
* TODO: legacy template들을 전부 template 폴더로 모아둘 필요 있음
|
||||
* TODO: side effect를 제거
|
||||
*/
|
||||
|
||||
/**
|
||||
* 관리자 권한이 필요함을 출력.
|
||||
* @return void
|
||||
*/
|
||||
function requireAdminPermissionHTML()
|
||||
{
|
||||
ob_start();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>관리메뉴</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||
<?= WebUtil::printCSS('css/common.css') ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
관리자가 아닙니다.<br>
|
||||
<?= banner() ?>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function turnTable()
|
||||
{
|
||||
|
||||
$turnList = [];
|
||||
$turnList[] = "<option selected value='0'>1턴</option>";
|
||||
foreach (Util::range(1, GameConst::$maxTurn) as $turnIdx) {
|
||||
$turnText = $turnIdx + 1;
|
||||
$turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>";
|
||||
}
|
||||
|
||||
$turnText = join("\n", $turnList);
|
||||
|
||||
return "
|
||||
<select id='generalTurnSelector' name=turn[] size=11 multiple>
|
||||
<option value='-3'>전체</option>
|
||||
<option value='-1'>홀턴</option>
|
||||
<option value='-2'>짝턴</option>
|
||||
{$turnText}
|
||||
</select>
|
||||
";
|
||||
}
|
||||
|
||||
function chiefTurnTable()
|
||||
{
|
||||
$turnList = [];
|
||||
$turnList[] = "<option selected value='0'>1턴</option>";
|
||||
foreach (Util::range(1, GameConst::$maxChiefTurn) as $turnIdx) {
|
||||
$turnText = $turnIdx + 1;
|
||||
$turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>";
|
||||
}
|
||||
|
||||
$turnText = join("\n", $turnList);
|
||||
|
||||
return "
|
||||
<select id='chiefTurnSelector' name=turn[] size=6 multiple>
|
||||
{$turnText}
|
||||
</select>
|
||||
";
|
||||
}
|
||||
|
||||
function displayiActionObjInfo(?iAction $action)
|
||||
{
|
||||
if ($action === null) {
|
||||
$info = '';
|
||||
$text = '-';
|
||||
} else {
|
||||
$info = $action->getInfo();
|
||||
$text = $action->getName();
|
||||
}
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $text,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
function displayCharInfo(string $type): string
|
||||
{
|
||||
$class = buildPersonalityClass($type);
|
||||
$info = $class->getInfo();
|
||||
$text = $class->getName();
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $text,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
|
||||
function displaySpecialWarInfo(?string $type): string
|
||||
{
|
||||
$class = buildGeneralSpecialWarClass($type);
|
||||
$info = $class->getInfo();
|
||||
$name = $class->getName();
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $name,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
|
||||
function displaySpecialDomesticInfo(?string $type): string
|
||||
{
|
||||
$class = buildGeneralSpecialDomesticClass($type);
|
||||
$info = $class->getInfo();
|
||||
$name = $class->getName();
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $name,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
|
||||
function allButton(bool $seizeNPCMode)
|
||||
{
|
||||
if ($seizeNPCMode) {
|
||||
$site = "a_npcList.php";
|
||||
$call = "빙의일람";
|
||||
} else {
|
||||
$site = "a_vote.php";
|
||||
$call = "설문조사";
|
||||
}
|
||||
|
||||
if (\file_exists(__DIR__ . "/d_setting/templates/allButton.php")) {
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/d_setting/templates');
|
||||
} else {
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
}
|
||||
|
||||
|
||||
return $templates->render('allButton', [
|
||||
'call' => $call,
|
||||
'site' => $site
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
function commandButton()
|
||||
{
|
||||
$session = Session::getInstance();
|
||||
$userID = Session::getUserID();
|
||||
if (!$session->isGameLoggedIn()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow("select no,nation,officer_level,belong,permission,penalty from general where owner=%i", $userID);
|
||||
|
||||
$nation = $db->queryFirstRow("select nation,level,color,secretlimit from nation where nation=%i", $me['nation']) ?? [
|
||||
'nation' => 0,
|
||||
'level' => 0,
|
||||
'secretlimit' => 99,
|
||||
'color' => '#000000'
|
||||
];
|
||||
|
||||
$bgColor = Util::array_get($nation['color']) ?: '#000000';
|
||||
$fgColor = newColor($bgColor);
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
$showSecret = false;
|
||||
$permission = checkSecretPermission($me);
|
||||
if ($permission >= 1) {
|
||||
$showSecret = true;
|
||||
} else if ($me['officer_level'] == 0) {
|
||||
$showSecret = false;
|
||||
}
|
||||
|
||||
return $templates->render('commandButton', [
|
||||
'bgColor' => $bgColor,
|
||||
'fgColor' => $fgColor,
|
||||
'meLevel' => $me['officer_level'],
|
||||
'nationLevel' => $nation['level'],
|
||||
'showSecret' => $showSecret,
|
||||
'permission' => $permission,
|
||||
]);
|
||||
}
|
||||
|
||||
function formatWounded(int $value, int $wound): string
|
||||
{
|
||||
if ($wound == 0) {
|
||||
return "$value";
|
||||
}
|
||||
$woundedValue = intdiv($value * (100 - $wound), 100);
|
||||
return "<font color=red>$woundedValue</font>";
|
||||
}
|
||||
|
||||
function formatDefenceTrain(int $value): string
|
||||
{
|
||||
if ($value === 999) {
|
||||
return "×";
|
||||
} else if ($value >= 80) {
|
||||
return "◎";
|
||||
} else {
|
||||
return "○";
|
||||
}
|
||||
}
|
||||
|
||||
function formatLeadershipBonus(int $value): string
|
||||
{
|
||||
if ($value == 0) {
|
||||
return '';
|
||||
}
|
||||
return "<font color=cyan>+{$value}</font>";
|
||||
}
|
||||
|
||||
function formatName(string $name, int $npc): string
|
||||
{
|
||||
if ($npc == 1) {
|
||||
$name = "<font color='skyblue'>$name</font>";
|
||||
} else if ($npc > 1) {
|
||||
$name = "<font color='cyan'>$name</font>";
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
function getMapHtml(?string $mapTheme = null)
|
||||
{
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
if ($mapTheme === null) {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
||||
}
|
||||
|
||||
return $templates->render('map', [
|
||||
'mapTheme' => $mapTheme
|
||||
]);
|
||||
}
|
||||
|
||||
function getInvitationList(array $nationList)
|
||||
{
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
foreach ($nationList as &$nation) {
|
||||
$nation['textColor'] = newColor($nation['color']);
|
||||
}
|
||||
return $templates->render('invitationList', [
|
||||
'nationList' => $nationList
|
||||
]);
|
||||
}
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
|
||||
/**
|
||||
* 템플릿 생성과 관련된 함수들을 모아두는 파일
|
||||
*
|
||||
* NOTE: 아직 converter와 명확한 구분이 되어있지 않음.
|
||||
* TODO: legacy template들을 전부 template 폴더로 모아둘 필요 있음
|
||||
* TODO: side effect를 제거
|
||||
*/
|
||||
|
||||
/**
|
||||
* 관리자 권한이 필요함을 출력.
|
||||
* @return void
|
||||
*/
|
||||
function requireAdminPermissionHTML()
|
||||
{
|
||||
ob_start();
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>관리메뉴</title>
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?= WebUtil::printCSS('../d_shared/common.css') ?>
|
||||
<?= WebUtil::printCSS('css/common.css') ?>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
관리자가 아닙니다.<br>
|
||||
<?= banner() ?>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
<?php
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
function turnTable()
|
||||
{
|
||||
|
||||
$turnList = [];
|
||||
$turnList[] = "<option selected value='0'>1턴</option>";
|
||||
foreach (Util::range(1, GameConst::$maxTurn) as $turnIdx) {
|
||||
$turnText = $turnIdx + 1;
|
||||
$turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>";
|
||||
}
|
||||
|
||||
$turnText = join("\n", $turnList);
|
||||
|
||||
return "
|
||||
<select id='generalTurnSelector' name=turn[] size=11 multiple>
|
||||
<option value='-3'>전체</option>
|
||||
<option value='-1'>홀턴</option>
|
||||
<option value='-2'>짝턴</option>
|
||||
{$turnText}
|
||||
</select>
|
||||
";
|
||||
}
|
||||
|
||||
function chiefTurnTable()
|
||||
{
|
||||
$turnList = [];
|
||||
$turnList[] = "<option selected value='0'>1턴</option>";
|
||||
foreach (Util::range(1, GameConst::$maxChiefTurn) as $turnIdx) {
|
||||
$turnText = $turnIdx + 1;
|
||||
$turnList[] = "<option value='{$turnIdx}'>{$turnText}턴</option>";
|
||||
}
|
||||
|
||||
$turnText = join("\n", $turnList);
|
||||
|
||||
return "
|
||||
<select id='chiefTurnSelector' name=turn[] size=6 multiple>
|
||||
{$turnText}
|
||||
</select>
|
||||
";
|
||||
}
|
||||
|
||||
function displayiActionObjInfo(?iAction $action)
|
||||
{
|
||||
if ($action === null) {
|
||||
$info = '';
|
||||
$text = '-';
|
||||
} else {
|
||||
$info = $action->getInfo();
|
||||
$text = $action->getName();
|
||||
}
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $text,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
function displayCharInfo(string $type): string
|
||||
{
|
||||
$class = buildPersonalityClass($type);
|
||||
$info = $class->getInfo();
|
||||
$text = $class->getName();
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $text,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
|
||||
function displaySpecialWarInfo(?string $type): string
|
||||
{
|
||||
$class = buildGeneralSpecialWarClass($type);
|
||||
$info = $class->getInfo();
|
||||
$name = $class->getName();
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $name,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
|
||||
function displaySpecialDomesticInfo(?string $type): string
|
||||
{
|
||||
$class = buildGeneralSpecialDomesticClass($type);
|
||||
$info = $class->getInfo();
|
||||
$name = $class->getName();
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
return $templates->render('tooltip', [
|
||||
'text' => $name,
|
||||
'info' => $info,
|
||||
]);
|
||||
}
|
||||
|
||||
function allButton(bool $seizeNPCMode)
|
||||
{
|
||||
if ($seizeNPCMode) {
|
||||
$site = "a_npcList.php";
|
||||
$call = "빙의일람";
|
||||
} else {
|
||||
$site = "a_vote.php";
|
||||
$call = "설문조사";
|
||||
}
|
||||
|
||||
if (\file_exists(__DIR__ . "/d_setting/templates/allButton.php")) {
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/d_setting/templates');
|
||||
} else {
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
}
|
||||
|
||||
|
||||
return $templates->render('allButton', [
|
||||
'call' => $call,
|
||||
'site' => $site
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
function commandButton()
|
||||
{
|
||||
$session = Session::getInstance();
|
||||
$userID = Session::getUserID();
|
||||
if (!$session->isGameLoggedIn()) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow("select no,nation,officer_level,belong,permission,penalty from general where owner=%i", $userID);
|
||||
|
||||
$nation = $db->queryFirstRow("select nation,level,color,secretlimit from nation where nation=%i", $me['nation']) ?? [
|
||||
'nation' => 0,
|
||||
'level' => 0,
|
||||
'secretlimit' => 99,
|
||||
'color' => '#000000'
|
||||
];
|
||||
|
||||
$bgColor = Util::array_get($nation['color']) ?: '#000000';
|
||||
$fgColor = newColor($bgColor);
|
||||
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
$showSecret = false;
|
||||
$permission = checkSecretPermission($me);
|
||||
if ($permission >= 1) {
|
||||
$showSecret = true;
|
||||
} else if ($me['officer_level'] == 0) {
|
||||
$showSecret = false;
|
||||
}
|
||||
|
||||
return $templates->render('commandButton', [
|
||||
'bgColor' => $bgColor,
|
||||
'fgColor' => $fgColor,
|
||||
'meLevel' => $me['officer_level'],
|
||||
'nationLevel' => $nation['level'],
|
||||
'showSecret' => $showSecret,
|
||||
'permission' => $permission,
|
||||
]);
|
||||
}
|
||||
|
||||
function formatWounded(int $value, int $wound): string
|
||||
{
|
||||
if ($wound == 0) {
|
||||
return "$value";
|
||||
}
|
||||
$woundedValue = intdiv($value * (100 - $wound), 100);
|
||||
return "<font color=red>$woundedValue</font>";
|
||||
}
|
||||
|
||||
function formatDefenceTrain(int $value): string
|
||||
{
|
||||
if ($value === 999) {
|
||||
return "×";
|
||||
} else if ($value >= 90){
|
||||
return "☆";
|
||||
} else if ($value >= 80) {
|
||||
return "◎";
|
||||
} else if ($value >= 60) {
|
||||
return "○";
|
||||
} else{
|
||||
return "△";
|
||||
}
|
||||
}
|
||||
|
||||
function formatLeadershipBonus(int $value): string
|
||||
{
|
||||
if ($value == 0) {
|
||||
return '';
|
||||
}
|
||||
return "<font color=cyan>+{$value}</font>";
|
||||
}
|
||||
|
||||
function formatName(string $name, int $npc): string
|
||||
{
|
||||
if ($npc == 1) {
|
||||
$name = "<font color='skyblue'>$name</font>";
|
||||
} else if ($npc > 1) {
|
||||
$name = "<font color='cyan'>$name</font>";
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
|
||||
function getMapHtml(?string $mapTheme = null)
|
||||
{
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
if ($mapTheme === null) {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
||||
}
|
||||
|
||||
return $templates->render('map', [
|
||||
'mapTheme' => $mapTheme
|
||||
]);
|
||||
}
|
||||
|
||||
function getInvitationList(array $nationList)
|
||||
{
|
||||
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
|
||||
|
||||
foreach ($nationList as &$nation) {
|
||||
$nation['textColor'] = newColor($nation['color']);
|
||||
}
|
||||
return $templates->render('invitationList', [
|
||||
'nationList' => $nationList
|
||||
]);
|
||||
}
|
||||
|
||||
+151
-104
@@ -8,8 +8,7 @@ function processTournament() {
|
||||
|
||||
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time']);
|
||||
$now = new \DateTime();
|
||||
$admin['now'] = $now->format('Y-m-d H:i:s');
|
||||
$admin['offset'] = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp();
|
||||
$offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp();
|
||||
|
||||
//수동일땐 무시
|
||||
if($admin['tnmt_auto'] == 0) { return; }
|
||||
@@ -18,99 +17,102 @@ function processTournament() {
|
||||
$tnmt = $admin['tournament'];
|
||||
$phase = $admin['phase'];
|
||||
|
||||
if($offset < 0){
|
||||
return;
|
||||
}
|
||||
|
||||
//현시간이 스탬프 지나친경우
|
||||
if($admin['offset'] >= 0) {
|
||||
switch($admin['tnmt_auto']) {
|
||||
case 1: $unit = 720; break;
|
||||
case 2: $unit = 420; break;
|
||||
case 3: $unit = 180; break;
|
||||
case 4: $unit = 60; break;
|
||||
case 5: $unit = 30; break;
|
||||
case 6: $unit = 15; break;
|
||||
case 7: $unit = 5; break;
|
||||
default: throw new MustNotBeReachedException();
|
||||
switch($admin['tnmt_auto']) {
|
||||
case 1: $unit = 720; break;
|
||||
case 2: $unit = 420; break;
|
||||
case 3: $unit = 180; break;
|
||||
case 4: $unit = 60; break;
|
||||
case 5: $unit = 30; break;
|
||||
case 6: $unit = 15; break;
|
||||
case 7: $unit = 5; break;
|
||||
default: throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
//업데이트 횟수
|
||||
$iter = intdiv($offset, $unit) + 1;
|
||||
|
||||
for($i=0; $i < $iter; $i++) {
|
||||
switch($tnmt) {
|
||||
case 1: //신청 마감
|
||||
fillLowGenAll();
|
||||
$tnmt = 2; $phase = 0;
|
||||
break;
|
||||
case 2: //예선중
|
||||
qualify($type, $tnmt, $phase); $phase++;
|
||||
if($phase >= 56) { $tnmt = 3; $phase = 0; }
|
||||
break;
|
||||
case 3: //추첨중
|
||||
selectionAll($type, $tnmt, $phase); $phase+=8;
|
||||
if($phase >= 32) { $tnmt = 4; $phase = 0; }
|
||||
break;
|
||||
case 4: //본선중
|
||||
finallySingle($type, $tnmt, $phase); $phase++;
|
||||
if($phase >= 6) { $tnmt = 5; $phase = 0; }
|
||||
break;
|
||||
case 5: //배정중
|
||||
final16set();
|
||||
$tnmt = 6; $phase = 0;
|
||||
startBetting();
|
||||
break;
|
||||
case 6: //베팅중
|
||||
$tnmt = 7; $phase = 0;
|
||||
break;
|
||||
case 7: //16강중
|
||||
finalFight($type, $tnmt, $phase, 16); $phase++;
|
||||
if($phase >= 8) { $tnmt = 8; $phase = 0; }
|
||||
break;
|
||||
case 8: //8강중
|
||||
finalFight($type, $tnmt, $phase, 8); $phase++;
|
||||
if($phase >= 4) { $tnmt = 9; $phase = 0; }
|
||||
break;
|
||||
case 9: //4강중
|
||||
finalFight($type, $tnmt, $phase, 4); $phase++;
|
||||
if($phase >= 2) { $tnmt = 10; $phase = 0; }
|
||||
break;
|
||||
case 10: //결승중
|
||||
finalFight($type, $tnmt, $phase, 2);
|
||||
$tnmt = 0; $phase = 0;
|
||||
setGift($type, $tnmt, $phase);
|
||||
$i = $iter;
|
||||
break;
|
||||
}
|
||||
|
||||
//업데이트 횟수
|
||||
$iter = intdiv($admin['offset'], $unit) + 1;
|
||||
//베팅은 무조건 60페이즈후 진행(최대 1시간)
|
||||
if($tnmt == 6) {
|
||||
$betTerm = $unit * 60;
|
||||
if($betTerm > 3600) { $betTerm = 3600; }
|
||||
//처리 초 더한 날짜
|
||||
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i + $betTerm);
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = $dt;
|
||||
return;
|
||||
}
|
||||
|
||||
for($i=0; $i < $iter; $i++) {
|
||||
switch($tnmt) {
|
||||
case 1: //신청 마감
|
||||
fillLowGenAll();
|
||||
$tnmt = 2; $phase = 0;
|
||||
break;
|
||||
case 2: //예선중
|
||||
qualify($type, $tnmt, $phase); $phase++;
|
||||
if($phase >= 56) { $tnmt = 3; $phase = 0; }
|
||||
break;
|
||||
case 3: //추첨중
|
||||
selectionAll($type, $tnmt, $phase); $phase+=8;
|
||||
if($phase >= 32) { $tnmt = 4; $phase = 0; }
|
||||
break;
|
||||
case 4: //본선중
|
||||
finallySingle($type, $tnmt, $phase); $phase++;
|
||||
if($phase >= 6) { $tnmt = 5; $phase = 0; }
|
||||
break;
|
||||
case 5: //배정중
|
||||
final16set();
|
||||
$tnmt = 6; $phase = 0;
|
||||
break;
|
||||
case 6: //베팅중
|
||||
$tnmt = 7; $phase = 0;
|
||||
break;
|
||||
case 7: //16강중
|
||||
finalFight($type, $tnmt, $phase, 16); $phase++;
|
||||
if($phase >= 8) { $tnmt = 8; $phase = 0; }
|
||||
break;
|
||||
case 8: //8강중
|
||||
finalFight($type, $tnmt, $phase, 8); $phase++;
|
||||
if($phase >= 4) { $tnmt = 9; $phase = 0; }
|
||||
break;
|
||||
case 9: //4강중
|
||||
finalFight($type, $tnmt, $phase, 4); $phase++;
|
||||
if($phase >= 2) { $tnmt = 10; $phase = 0; }
|
||||
break;
|
||||
case 10: //결승중
|
||||
finalFight($type, $tnmt, $phase, 2);
|
||||
$tnmt = 0; $phase = 0;
|
||||
setGift($type, $tnmt, $phase);
|
||||
$i = $iter;
|
||||
break;
|
||||
}
|
||||
|
||||
//베팅은 무조건 60페이즈후 진행(최대 1시간)
|
||||
if($tnmt == 6) {
|
||||
$betTerm = $unit * 60;
|
||||
if($betTerm > 3600) { $betTerm = 3600; }
|
||||
//처리 초 더한 날짜
|
||||
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i + $betTerm);
|
||||
if($admin['tnmt_auto'] == 1) {
|
||||
//처리 초 더한 날짜
|
||||
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i);
|
||||
$hr = substr($dt, 11, 2);
|
||||
//지정시간대 넘어가면 중단 20~24시
|
||||
if($hr < 20) {
|
||||
$dt = substr($dt, 0, 11)."20:00:00";
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = $dt;
|
||||
return;
|
||||
}
|
||||
|
||||
if($admin['tnmt_auto'] == 1) {
|
||||
//처리 초 더한 날짜
|
||||
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i);
|
||||
$hr = substr($dt, 11, 2);
|
||||
//지정시간대 넘어가면 중단 20~24시
|
||||
if($hr < 20) {
|
||||
$dt = substr($dt, 0, 11)."20:00:00";
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = $dt;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$second = $unit * $iter;
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
$second = $unit * $iter;
|
||||
$gameStor->tournament = $tnmt;
|
||||
$gameStor->phase = $phase;
|
||||
$gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
function getTournamentTerm() {
|
||||
@@ -173,7 +175,7 @@ function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl,
|
||||
if($prmt > 0) { $name = "<font color=orange>".$name."</font>"; }
|
||||
elseif($npc >= 2) { $name = "<font color=cyan>".$name."</font>"; }
|
||||
elseif($npc == 1) { $name = "<font color=skyblue>".$name."</font>"; }
|
||||
echo "<tr align=center><td id=bg2>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>";
|
||||
echo "<tr align=center><td class='bg2'>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>";
|
||||
}
|
||||
|
||||
function printFighting($tournament, $phase) {
|
||||
@@ -246,7 +248,7 @@ function startTournament($auto, $type) {
|
||||
}
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month']);
|
||||
|
||||
|
||||
$gameStor->tnmt_auto = $auto;
|
||||
$gameStor->tnmt_time = (new \DateTimeImmutable())->add(new \DateInterval("PT{$unit}M"))->format('Y-m-d H:i:s');
|
||||
$gameStor->tournament = 1;
|
||||
@@ -296,11 +298,51 @@ function startTournament($auto, $type) {
|
||||
['설전','책사'],
|
||||
][$type];
|
||||
|
||||
$history[] = "<S>◆</>{$admin['year']}년 {$admin['month']}월:{$openerText}<C>{$typeText}</> 대회가 개최됩니다! 천하의 <span class='ev_highlight'>{$genTypeText}</span>들을 모집하고 있습니다!";
|
||||
|
||||
$history[] = "<S>◆</>{$admin['year']}년 {$admin['month']}월:<B><b>【대회】</b></>{$openerText}<C>{$typeText}</> 대회가 개최됩니다! 천하의 <span class='ev_highlight'>{$genTypeText}</span>들을 모집하고 있습니다!";
|
||||
|
||||
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
|
||||
}
|
||||
|
||||
function startBetting(){
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
|
||||
pushGlobalHistoryLog([
|
||||
"<S>◆</>{$year}년 {$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!"
|
||||
], $year, $month);
|
||||
|
||||
$betGold = 10;
|
||||
|
||||
$npcList = $db->queryFirstColumn('SELECT no FROM general WHERE npc >= 2 AND gold >= (500 + %i)', $betGold);
|
||||
$npcBet = [];
|
||||
$betSum = [
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0,
|
||||
];
|
||||
|
||||
foreach($npcList as $npcID){
|
||||
$target = Util::randRangeInt(0, 15);
|
||||
$betSum[$target] += $betGold;
|
||||
$npcBet[] = [$npcID, $target];
|
||||
}
|
||||
|
||||
$db->update('general', [
|
||||
'gold'=>$db->sqleval('gold - %i', $betGold),
|
||||
], 'no IN %li', $npcList);
|
||||
foreach($npcBet as [$npcID, $betTarget]){
|
||||
$targetKey = "bet{$betTarget}";
|
||||
$db->update('betting', [
|
||||
"bet{$betTarget}"=>$db->sqleval('%b + %i', $targetKey, $betGold),
|
||||
], 'general_id = %i', $npcID);
|
||||
}
|
||||
foreach($betSum as $betTarget=>$betSumGold){
|
||||
$targetKey = "bet{$betTarget}";
|
||||
$db->update('betting', [
|
||||
"bet{$betTarget}"=>$db->sqleval('%b + %i', $targetKey, $betSumGold),
|
||||
], 'general_id = 0');
|
||||
}
|
||||
}
|
||||
|
||||
function fillLowGenAll() {
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
@@ -523,7 +565,7 @@ function selection($tnmt_type, $tnmt, $phase) {
|
||||
if($phase < 31) {
|
||||
$gameStor->phase+=1;
|
||||
} else {
|
||||
$gameStor->tournamemt = 4;
|
||||
$gameStor->tournament = 4;
|
||||
$gameStor->phase=0;
|
||||
}
|
||||
}
|
||||
@@ -689,7 +731,8 @@ function setGift($tnmt_type, $tnmt, $phase) {
|
||||
'grp_no'=>$general['grp_no'],
|
||||
'reward'=>$cost,
|
||||
'msg'=>"<span class='ev_highlight'>16강 진출</span>",
|
||||
'logger'=>$logger
|
||||
'logger'=>$logger,
|
||||
'inheritance_point'=>10,
|
||||
];
|
||||
}
|
||||
//8강자 명성 돈
|
||||
@@ -723,6 +766,7 @@ function setGift($tnmt_type, $tnmt, $phase) {
|
||||
//포상 장수 이름, 금액
|
||||
$resultHelper[$generalID]['reward'] += $cost;
|
||||
$resultHelper[$generalID]['msg'] = "<span class='ev_highlight'>4강 진출</span>";
|
||||
General::createGeneralObjFromDB($generalID)->increaseInheritancePoint('tournament', 10);
|
||||
}
|
||||
//결승자 명성 돈
|
||||
$cost = $admin['develcost'] * 6;
|
||||
@@ -739,6 +783,7 @@ function setGift($tnmt_type, $tnmt, $phase) {
|
||||
//포상 장수 이름, 금액
|
||||
$resultHelper[$generalID]['reward'] += $cost;
|
||||
$resultHelper[$generalID]['msg'] = "<span class='ev_highlight'>준우승</span>으";
|
||||
$resultHelper[$generalID]['inheritance_point'] = 50;
|
||||
if($general['lose'] > 0){
|
||||
$runnerUp = $general;
|
||||
}
|
||||
@@ -761,6 +806,7 @@ function setGift($tnmt_type, $tnmt, $phase) {
|
||||
//포상 장수 이름, 금액
|
||||
$resultHelper[$generalID]['reward'] += $cost;
|
||||
$resultHelper[$generalID]['msg'] = "<span class='ev_highlight'>우승</span>으";
|
||||
$resultHelper[$generalID]['inheritance_point'] = 100;
|
||||
$winner = $general;
|
||||
}
|
||||
|
||||
@@ -775,23 +821,24 @@ function setGift($tnmt_type, $tnmt, $phase) {
|
||||
$runnerUpLogger = $resultHelper[$runnerUp['no']]['logger'];
|
||||
$runnerUpLogger->pushGeneralHistoryLog("<C>{$tp}</> 대회에서 준우승");
|
||||
|
||||
|
||||
|
||||
|
||||
$winnerRewardText = number_format($resultHelper[$winner['no']]['reward']);
|
||||
$runnerUpRewardText = number_format($resultHelper[$runnerUp['no']]['reward']);
|
||||
|
||||
$josaYiWinner = JosaUtil::pick($winner['name'], '이');
|
||||
$josaYiRunnerUp = JosaUtil::pick($runnerUp['name'], '이');
|
||||
|
||||
$winnerLogger->pushGlobalHistoryLog("<C>{$tp}</> 대회에서 <Y>{$winner['name']}</>{$josaYiWinner} <C>우승</>, <Y>{$runnerUp['name']}</>{$josaYiRunnerUp} <C>준우승</>을 차지하여 천하에 이름을 떨칩니다!", ActionLogger::EVENT_YEAR_MONTH);
|
||||
$winnerLogger->pushGlobalHistoryLog("<C>{$tp}</> 대회의 <S>우승자</>에게는 <C>{$winnerRewardText}</>, <S>준우승자</>에겐 <C>{$runnerUpRewardText}</>의 <S>상금</>과 약간의 <S>명성</>이 주어집니다!", ActionLogger::EVENT_YEAR_MONTH);
|
||||
|
||||
foreach($resultHelper as $general){
|
||||
$winnerLogger->pushGlobalHistoryLog("<B><b>【대회】</b></><C>{$tp}</> 대회에서 <Y>{$winner['name']}</>{$josaYiWinner} <C>우승</>, <Y>{$runnerUp['name']}</>{$josaYiRunnerUp} <C>준우승</>을 차지하여 천하에 이름을 떨칩니다!", ActionLogger::EVENT_YEAR_MONTH);
|
||||
$winnerLogger->pushGlobalHistoryLog("<B><b>【대회】</b></><C>{$tp}</> 대회의 <S>우승자</>에게는 <C>{$winnerRewardText}</>, <S>준우승자</>에겐 <C>{$runnerUpRewardText}</>의 <S>상금</>과 약간의 <S>명성</>이 주어집니다!", ActionLogger::EVENT_YEAR_MONTH);
|
||||
|
||||
$generalObjList = General::createGeneralObjListFromDB(array_keys($resultHelper));
|
||||
|
||||
foreach($resultHelper as $generalID=>$general){
|
||||
$rewardText = number_format($general['reward']);
|
||||
/** @var ActionLogger */
|
||||
$logger = $general['logger'];
|
||||
$logger->pushGeneralActionLog("<C>{$tp}</> 대회의 {$general['msg']}로 <C>{$rewardText}</>의 <S>상금</>, 약간의 <S>명성</> 획득!", ActionLogger::EVENT_PLAIN);
|
||||
//TODO: 토너먼트의 다른 값이 모두 sql에 직접 입력하므로 기반을 바꿔야함.
|
||||
$generalObjList[$generalID]->increaseInheritancePoint('tournament', $general['inheritance_point']);
|
||||
}
|
||||
|
||||
//우승자 번호
|
||||
@@ -829,7 +876,7 @@ function setRefund() {
|
||||
$db->update('general', [
|
||||
'gold'=>$db->sqleval('gold + %i', $cost)
|
||||
], 'no IN %li', $generalIDList);
|
||||
|
||||
|
||||
//베팅금 환수
|
||||
$db->update(['general', [
|
||||
'gold'=>$db->sqleval('gold + (SELECT bet0+bet1+bet2+bet3+bet4+bet5+bet6+bet7+bet8+bet9+bet10+bet11+bet12+bet13+bet14+bet15 FROM betting WHERE general_id = general.no)')
|
||||
@@ -862,16 +909,16 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type) {
|
||||
if($type == 0) { $turn = 10; }
|
||||
else { $turn = 100; }
|
||||
|
||||
|
||||
|
||||
if($tnmt_type == 1) { $tp = "leadership"; $tp2 = "tl"; }
|
||||
elseif($tnmt_type == 2) { $tp = "strength"; $tp2 = "ts"; }
|
||||
elseif($tnmt_type == 3) { $tp = "intel"; $tp2 = "ti"; }
|
||||
else /*$tnmt_type == 0*/{ $tp = "total"; $tp2 = "tt"; }
|
||||
else /*$tnmt_type == 0*/{ $tp = "total"; $tp2 = "tt"; }
|
||||
|
||||
$e1 = $energy1 = Util::round($gen1[$tp] * getLog($gen1['lvl'], $gen2['lvl']) * 10);
|
||||
$e2 = $energy2 = Util::round($gen2[$tp] * getLog($gen1['lvl'], $gen2['lvl']) * 10);
|
||||
|
||||
|
||||
|
||||
|
||||
foreach([$gen1, $gen2] as $gen){
|
||||
$horse = buildItemClass($gen['h']);
|
||||
@@ -883,7 +930,7 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type) {
|
||||
$itemName = $horse->getName();
|
||||
$itemRawName = $horse->getRawName();
|
||||
switch(rand()%4) {
|
||||
case 0:
|
||||
case 0:
|
||||
$josaYi = JosaUtil::pick($itemRawName, '이');
|
||||
$log[] = "<S>●</> <Y>{$gen['name']}</>의 <S>{$itemName}</>{$josaYi} 포효합니다!"; break;
|
||||
case 1:
|
||||
@@ -1085,7 +1132,7 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type) {
|
||||
'lose'=>$db->sqleval('lose+1'),
|
||||
'gl'=>$db->sqleval('gl-%i', $gl)
|
||||
], 'grp=%i AND grp_no=%i', $group, $g2);
|
||||
|
||||
|
||||
if($general1['gl'] > $general2['gl']) { $gl1 = 1; $gl2 = 0; }
|
||||
elseif($general1['gl'] == $general2['gl']) { $gl1 = 2; $gl2 = -1; }
|
||||
else { $gl1 = 3; $gl2 = -2; }
|
||||
@@ -1127,7 +1174,7 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type) {
|
||||
$gen1resKey = 'd';
|
||||
$gen2resKey = 'd';
|
||||
break;
|
||||
default: new MustNotBeReachedException();
|
||||
default: throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
$db->update('rank_data', [
|
||||
|
||||
+11
-17
@@ -61,7 +61,7 @@ $scenario = $gameStor->scenario_text;
|
||||
$nationID = $generalObj->getNationID();
|
||||
if($nationID){
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationStor->cacheValues(['notice', 'online_genenerals']);
|
||||
$nationStor->cacheAll();
|
||||
}
|
||||
|
||||
$valid = 0;
|
||||
@@ -79,9 +79,11 @@ if ($gameStor->fiction == 0) {
|
||||
}
|
||||
if ($gameStor->npcmode == 0) {
|
||||
$npcmode = "불가능";
|
||||
} else {
|
||||
} else if($gameStor->npcmode == 1){
|
||||
$npcmode = "가능";
|
||||
$valid = 1;
|
||||
} else {
|
||||
$npcmode = "선택 생성";
|
||||
}
|
||||
$color = "cyan";
|
||||
$mapTheme = $gameStor->map_theme;
|
||||
@@ -95,18 +97,10 @@ $serverCnt = $gameStor->server_cnt;
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=1024" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery.redirect.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/moment.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/linkify/linkify.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/linkify/linkify-string.min.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/main.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('d_shared/base_map.js')?>
|
||||
<?=WebUtil::printJS('js/map.js')?>
|
||||
<?=WebUtil::printJS('js/msg.js')?>
|
||||
<?=WebUtil::printJS('dist_js/main.js')?>
|
||||
<script>
|
||||
window.serverNick = '<?=DB::prefix()?>';
|
||||
window.serverID = '<?=UniqueConst::$serverID?>';
|
||||
@@ -134,7 +128,7 @@ $(function(){
|
||||
<body class="img_back">
|
||||
|
||||
<div id="container">
|
||||
<div><?=allButton($gameStor->npcmode!=0)?></div>
|
||||
<div><?=allButton($gameStor->npcmode==1)?></div>
|
||||
<table class="tb_layout bg0" style="width:1000px;">
|
||||
<tr height=50>
|
||||
<td colspan=5 id="server_title" align=center><font size=4>삼국지 모의전투 HiDCHe <?=$serverName.$serverCnt?>기 (<font color=cyan><?=$scenario?></font>)</font></td>
|
||||
@@ -293,7 +287,7 @@ else if($session->userGrade == 4){
|
||||
style='background-color:<?=GameConst::$basecolor2?>;color:white;width:70px;font-size:13px;margin-left:1ch;margin-right:2ch;'
|
||||
><input type=button value='▼미루기' id='pushTurn'
|
||||
style='background-color:<?=GameConst::$basecolor2?>;color:white;width:80px;font-size:13px;'
|
||||
><input type=button value='▲당기기' id='pullTurn'
|
||||
><input type=button value='▲당기기' id='pullTurn'
|
||||
style='background-color:<?=GameConst::$basecolor2?>;color:white;width:80px;font-size:13px;'
|
||||
></td>
|
||||
</tr>
|
||||
@@ -304,7 +298,7 @@ else if($session->userGrade == 4){
|
||||
style='background-color:<?=GameConst::$basecolor2?>;color:white;width:110px;font-size:13px;'
|
||||
><input type=button value='갱 신' id='refreshPage'
|
||||
style='background-color:<?=GameConst::$basecolor2?>;color:white;width:110px;font-size:13px;'
|
||||
><input type=button value='로비로' onclick="location.replace('../')"
|
||||
><input type=button value='로비로' onclick="location.replace('../')"
|
||||
style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;font-size:13px;
|
||||
>
|
||||
</td>
|
||||
@@ -341,7 +335,7 @@ else if($session->userGrade == 4){
|
||||
<button id="msg_submit">서신전달&갱신</button><br>
|
||||
내용 없이 '서신전달&갱신'을 누르면 메세지창이 갱신됩니다.
|
||||
</div>
|
||||
<div><?=allButton($gameStor->npcmode!=0)?></div>
|
||||
<div><?=allButton($gameStor->npcmode==1)?></div>
|
||||
<div id="message_board"><div style="left:0;" class="board_side bg0">
|
||||
<div class="board_header bg0" id='public_talk_position'>전체 메시지(최고99자)</div>
|
||||
<section class="public_message">
|
||||
@@ -361,7 +355,7 @@ else if($session->userGrade == 4){
|
||||
<button type="button" class="load_old_message btn btn-secondary btn-block" data-msg_type="diplomacy">이전 메시지 불러오기</button>
|
||||
</section>
|
||||
</div></div>
|
||||
<div style="clear:left;"><?=allButton($gameStor->npcmode!=0)?><?=banner()?></div>
|
||||
<div style="clear:left;"><?=allButton($gameStor->npcmode==1)?><?=banner()?></div>
|
||||
</div>
|
||||
<?php
|
||||
if ($con == 1) {
|
||||
|
||||
+35
-20
@@ -14,7 +14,7 @@ $serverName = DB::prefix();
|
||||
$serverAcl = $session->acl[$serverName]??[];
|
||||
$allowReset = in_array('reset', $serverAcl);
|
||||
$allowFullReset = in_array('fullReset',$serverAcl);
|
||||
$allowReset |= $allowFullReset;
|
||||
$allowReset = $allowReset || $allowFullReset;
|
||||
|
||||
if($session->userGrade < 5 && !$allowReset){
|
||||
die('관리자 아님');
|
||||
@@ -28,11 +28,9 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery.validate.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/install.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/install.js')?>
|
||||
<?=WebUtil::printCSS('css/normalize.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('css/install.css')?>
|
||||
@@ -47,7 +45,7 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
<h3 class="card-header">
|
||||
설치(환경 설정)
|
||||
<!--턴시간, 시간동기화, 시나리오, 상성, 확장장수, NPC유저, 이미지설정-->
|
||||
</h3>
|
||||
</h3>
|
||||
<div class="card-body">
|
||||
<form id="game_form" method="post" action="#">
|
||||
<div class="form-group row">
|
||||
@@ -82,7 +80,7 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="sync" class="col-sm-3 col-form-label">시간 동기화</label>
|
||||
<div class="col-sm-9" style="display: inline-flex;">
|
||||
@@ -93,7 +91,7 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="sync" value="0">N
|
||||
</label>
|
||||
|
||||
|
||||
</div>
|
||||
<small class="text-muted">
|
||||
시간 단위에 맞게 년/월이 설정됩니다. <br>예: 120분(오전1시=1월), 60분(오전/오후 1시=1월)
|
||||
@@ -102,11 +100,11 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="confirm_password" class="col-sm-3 col-form-label">시나리오 선택</label>
|
||||
<label for="scenario_sel" class="col-sm-3 col-form-label">시나리오 선택</label>
|
||||
<div class="col-sm-9">
|
||||
<select class="form-control" name="scenario" size="1" id="scenario_sel">
|
||||
</select>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -138,6 +136,20 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="block_general_create" class="col-sm-3 col-form-label">장수 임의 생성</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="block_general_create" class="btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="block_general_create" value="0" checked>가능
|
||||
</label>
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="block_general_create" value="1">불가
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="npcmode" class="col-sm-3 col-form-label">NPC 빙의</label>
|
||||
<div class="col-sm-9">
|
||||
@@ -148,35 +160,38 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="npcmode" value="0" checked>불가
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="radio" name="npcmode" value="2">선택 생성 가능
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group row">
|
||||
<label class="col-sm-3 col-form-label">휴식 턴 시 장수 턴</label>
|
||||
<label class="col-sm-3 col-form-label" id="autorun_set_label">휴식 턴 시 장수 턴</label>
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend btn-group btn-group-toggle" data-toggle="buttons">
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="develop" name="autorun_develop" id="autorun_develop">내정
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="develop" name="autorun_user[]" value="develop">내정
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="warp" name="autorun_warp" id="autorun_warp">순간이동
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="warp" name="autorun_user[]" value="warp">순간이동
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="recruit" name="autorun_recruit" id="autorun_recruit">징병
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="recruit" name="autorun_user[]" value="recruit">징병
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="recruit_high" name="autorun_recruit_high" id="autorun_recruit_high">모병
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="recruit_high" name="autorun_user[]" value="recruit_high">모병
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="train" name="autorun_train" id="autorun_train">훈사
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="train" name="autorun_user[]" value="train">훈사
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="battle" name="autorun_battle" id="autorun_battle">출병
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="battle" name="autorun_user[]" value="battle">출병
|
||||
</label>
|
||||
<label class="btn btn-secondary">
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="chief" name="autorun_chief" id="autorun_chief">기본 사령턴
|
||||
<input type="checkbox" class="autorun_user_chk" data-key="chief" name="autorun_user[]" value="chief">기본 사령턴
|
||||
</label>
|
||||
</div>
|
||||
<div class="input-group-append">
|
||||
@@ -351,7 +366,7 @@ if($session->userGrade < 5 && !$allowReset){
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><td colspan="2">
|
||||
|
||||
|
||||
</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
+7
-9
@@ -21,11 +21,9 @@ if($session->userGrade == 5){
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<?=WebUtil::printJS('../e_lib/jquery-3.3.1.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/bootstrap.bundle.min.js')?>
|
||||
<?=WebUtil::printJS('../e_lib/jquery.validate.min.js')?>
|
||||
<?=WebUtil::printJS('js/common.js')?>
|
||||
<?=WebUtil::printJS('js/install_db.js')?>
|
||||
<?=WebUtil::printJS('../d_shared/common_path.js')?>
|
||||
<?=WebUtil::printJS('dist_js/vendors.js')?>
|
||||
<?=WebUtil::printJS('dist_js/install_db.js')?>
|
||||
<?=WebUtil::printCSS('css/normalize.css')?>
|
||||
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
|
||||
<?=WebUtil::printCSS('css/install.css')?>
|
||||
@@ -39,7 +37,7 @@ if($session->userGrade == 5){
|
||||
<div class="card" id="db_form_card">
|
||||
<h3 class="card-header">
|
||||
설치(DB 설정)
|
||||
</h3>
|
||||
</h3>
|
||||
<div class="card-body">
|
||||
<form id="db_form" method="post" action="#">
|
||||
<?php if(class_exists('\\sammo\\DB')): ?>
|
||||
@@ -53,7 +51,7 @@ if($session->userGrade == 5){
|
||||
<label class="btn btn-secondary active">
|
||||
<input type="radio" name="full_reset" value="0" checked>N
|
||||
</label>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -73,7 +71,7 @@ if($session->userGrade == 5){
|
||||
<input type="text" class="form-control" name="db_port" id="db_port" placeholder="접속 포트" value="3306" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="db_id" class="col-sm-3 col-form-label">DB계정</label>
|
||||
<div class="col-sm-9">
|
||||
@@ -82,7 +80,7 @@ if($session->userGrade == 5){
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="form-group row">
|
||||
<label for="db_pw" class="col-sm-3 col-form-label">DB비밀번호</label>
|
||||
<div class="col-sm-9">
|
||||
|
||||
+101
-100
@@ -1,101 +1,102 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include 'lib.php';
|
||||
include "func.php";
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
if (!$db->queryFirstField("SHOW TABLES LIKE 'reserved_open'")) {
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'affected'=>0,
|
||||
'status'=>'no_reserved_table'
|
||||
]);
|
||||
}
|
||||
|
||||
$reserved = $db->queryFirstRow('SELECT `date`, options FROM reserved_open ORDER BY `date` ASC LIMIT 1');
|
||||
|
||||
if(!$reserved){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'affected'=>0,
|
||||
'status'=>'no_reserved'
|
||||
]);
|
||||
}
|
||||
|
||||
$reservedDate = new \DateTime($reserved['date']);
|
||||
$now = new \DateTime();
|
||||
|
||||
|
||||
$status = 'not_yet';
|
||||
|
||||
list($isUnited, $lastTurn) = $gameStor->getValuesAsArray(['isunited', 'turntime']);
|
||||
if($isUnited === null || $lastTurn === null){
|
||||
$isUnited = 2;
|
||||
$lastTurn = '2000-01-01';
|
||||
}
|
||||
|
||||
if($lastTurn !== null){
|
||||
$lastTurn = new \DateTime($lastTurn);
|
||||
}
|
||||
|
||||
if($lastTurn === null){
|
||||
//이미 리셋된 상태임
|
||||
}
|
||||
else if(file_exists(__DIR__.'/.htaccess')){
|
||||
//일단 서버는 닫혀 있음
|
||||
}
|
||||
else if(
|
||||
$isUnited == 2 &&
|
||||
$now->getTimestamp() - $lastTurn->getTimestamp() > $reservedDate->getTimestamp() - $now->getTimestamp()
|
||||
){
|
||||
//정지 상태 & 중간 넘음
|
||||
AppConf::getList()[DB::prefix()]->closeServer();
|
||||
$status = 'closed';
|
||||
}
|
||||
else if(
|
||||
$isUnited > 0 &&
|
||||
$now->getTimestamp() - $lastTurn->getTimestamp() > ($reservedDate->getTimestamp() - $now->getTimestamp()) * 2
|
||||
){
|
||||
//천통 & 비정지 상태 & 2/3 넘음
|
||||
AppConf::getList()[DB::prefix()]->closeServer();
|
||||
$status = 'closed';
|
||||
}
|
||||
else if($reservedDate->getTimestamp() - $now->getTimestamp() <= 60*10){
|
||||
//어쨌든 간에 10분 남았다면.
|
||||
AppConf::getList()[DB::prefix()]->closeServer();
|
||||
$status = 'closed';
|
||||
}
|
||||
|
||||
if($now < $reservedDate){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'affected'=>0,
|
||||
'status'=>$status
|
||||
]);
|
||||
}
|
||||
|
||||
$options = Json::decode($reserved['options']);
|
||||
|
||||
$result = ResetHelper::buildScenario(
|
||||
$options['turnterm'],
|
||||
$options['sync'],
|
||||
$options['scenario'],
|
||||
$options['fiction'],
|
||||
$options['extend'],
|
||||
$options['npcmode'],
|
||||
$options['show_img_level'],
|
||||
$options['tournament_trig'],
|
||||
$options['join_mode'],
|
||||
$options['starttime'],
|
||||
$options['autorun_user']?:null
|
||||
);
|
||||
|
||||
$result['affected']=1;
|
||||
|
||||
$prefix = DB::prefix();
|
||||
AppConf::getList()[$prefix]->openServer();
|
||||
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include 'lib.php';
|
||||
include "func.php";
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
if (!$db->queryFirstField("SHOW TABLES LIKE 'reserved_open'")) {
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'affected'=>0,
|
||||
'status'=>'no_reserved_table'
|
||||
]);
|
||||
}
|
||||
|
||||
$reserved = $db->queryFirstRow('SELECT `date`, options FROM reserved_open ORDER BY `date` ASC LIMIT 1');
|
||||
|
||||
if(!$reserved){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'affected'=>0,
|
||||
'status'=>'no_reserved'
|
||||
]);
|
||||
}
|
||||
|
||||
$reservedDate = new \DateTime($reserved['date']);
|
||||
$now = new \DateTime();
|
||||
|
||||
|
||||
$status = 'not_yet';
|
||||
|
||||
list($isUnited, $lastTurn) = $gameStor->getValuesAsArray(['isunited', 'turntime']);
|
||||
if($isUnited === null || $lastTurn === null){
|
||||
$isUnited = 2;
|
||||
$lastTurn = '2000-01-01';
|
||||
}
|
||||
|
||||
if($lastTurn !== null){
|
||||
$lastTurn = new \DateTime($lastTurn);
|
||||
}
|
||||
|
||||
if($lastTurn === null){
|
||||
//이미 리셋된 상태임
|
||||
}
|
||||
else if(file_exists(__DIR__.'/.htaccess')){
|
||||
//일단 서버는 닫혀 있음
|
||||
}
|
||||
else if(
|
||||
$isUnited == 2 &&
|
||||
$now->getTimestamp() - $lastTurn->getTimestamp() > $reservedDate->getTimestamp() - $now->getTimestamp()
|
||||
){
|
||||
//정지 상태 & 중간 넘음
|
||||
ServConfig::getServerList()[DB::prefix()]->closeServer();
|
||||
$status = 'closed';
|
||||
}
|
||||
else if(
|
||||
$isUnited > 0 &&
|
||||
$now->getTimestamp() - $lastTurn->getTimestamp() > ($reservedDate->getTimestamp() - $now->getTimestamp()) * 2
|
||||
){
|
||||
//천통 & 비정지 상태 & 2/3 넘음
|
||||
ServConfig::getServerList()[DB::prefix()]->closeServer();
|
||||
$status = 'closed';
|
||||
}
|
||||
else if($reservedDate->getTimestamp() - $now->getTimestamp() <= 60*10){
|
||||
//어쨌든 간에 10분 남았다면.
|
||||
ServConfig::getServerList()[DB::prefix()]->closeServer();
|
||||
$status = 'closed';
|
||||
}
|
||||
|
||||
if($now < $reservedDate){
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'affected'=>0,
|
||||
'status'=>$status
|
||||
]);
|
||||
}
|
||||
|
||||
$options = Json::decode($reserved['options']);
|
||||
|
||||
$result = ResetHelper::buildScenario(
|
||||
$options['turnterm'],
|
||||
$options['sync'],
|
||||
$options['scenario'],
|
||||
$options['fiction'],
|
||||
$options['extend'],
|
||||
$options['block_general_create'],
|
||||
$options['npcmode'],
|
||||
$options['show_img_level'],
|
||||
$options['tournament_trig'],
|
||||
$options['join_mode'],
|
||||
$options['starttime'],
|
||||
$options['autorun_user']?:null
|
||||
);
|
||||
|
||||
$result['affected']=1;
|
||||
|
||||
$prefix = DB::prefix();
|
||||
ServConfig::getServerList()[$prefix]->openServer();
|
||||
|
||||
Json::die($result);
|
||||
@@ -5,9 +5,11 @@ include('lib.php');
|
||||
include 'func.php';
|
||||
|
||||
$result = [
|
||||
"generalID"=>null,
|
||||
"myNationID"=>null,
|
||||
"isChief"=>false
|
||||
"generalID"=>0,
|
||||
"myNationID"=>0,
|
||||
"isChief"=>false,
|
||||
"officerLevel"=>0,
|
||||
"permission"=>0,
|
||||
];
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$destGeneralID = Util::getPost('destGeneralID', 'int', 0);
|
||||
|
||||
if(!$destGeneralID || $destGeneralID <= 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 장수 코드입니다'
|
||||
]);
|
||||
}
|
||||
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
increaseRefresh("시뮬레이터 추출", 1);
|
||||
|
||||
$userID = Session::getUserID();
|
||||
$me = $db->queryFirstRow('SELECT no,nation from general where owner=%i', $userID);
|
||||
$nationID = $me['nation'];
|
||||
|
||||
$reqColumns = [
|
||||
'nation',
|
||||
'name', 'officer_level', 'explevel', 'injury',
|
||||
'leadership', 'horse', 'strength', 'weapon', 'intel', 'book', 'item',
|
||||
'rice', 'personal', 'special2',
|
||||
'crew', 'crewtype',
|
||||
'atmos', 'train', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5', 'defence_train',
|
||||
];
|
||||
|
||||
$reqRankColumns = [
|
||||
'warnum', 'killnum', 'killcrew'
|
||||
];
|
||||
|
||||
$dummyItems = [
|
||||
'officer_level'=>1,
|
||||
'horse'=>'None',
|
||||
'weapon'=>'None',
|
||||
'book'=>'None',
|
||||
'item'=>'None',
|
||||
'crew'=>0,
|
||||
'crewtype'=>GameUnitConst::DEFAULT_CREWTYPE,
|
||||
'rice'=>10000,
|
||||
'train'=>GameConst::$maxTrainByCommand,
|
||||
'atmos'=>GameConst::$maxTrainByCommand,
|
||||
'dex1'=>0,
|
||||
'dex2'=>0,
|
||||
'dex3'=>0,
|
||||
'dex4'=>0,
|
||||
'dex5'=>0,
|
||||
'defence_train'=>80,
|
||||
'warnum'=>0,
|
||||
'killnum'=>0,
|
||||
'killcrew'=>0,
|
||||
];
|
||||
|
||||
$rawDestGeneral = $db->queryFirstRow('SELECT %l FROM general WHERE no=%i', Util::formatListOfBackticks($reqColumns), $destGeneralID);
|
||||
|
||||
if($nationID == 0 || $rawDestGeneral['nation'] != $nationID){
|
||||
foreach($dummyItems as $key=>$val){
|
||||
$rawDestGeneral[$key] = $val;
|
||||
}
|
||||
}
|
||||
else{
|
||||
$rawRankValue = $db->queryAllLists('SELECT `type`, `value` FROM rank_data WHERE general_id = %i AND `type` IN %ls', $destGeneralID, $reqRankColumns);
|
||||
foreach($rawRankValue as [$rankType, $rankValue]){
|
||||
$rawDestGeneral[$rankType] = $rankValue;
|
||||
}
|
||||
}
|
||||
|
||||
foreach(['dex1', 'dex2', 'dex3', 'dex4', 'dex5'] as $dexKey){
|
||||
$dex = $rawDestGeneral[$dexKey];
|
||||
$rawDestGeneral[$dexKey] = getDexLevelList()[getDexLevel($dex)][0];
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'general'=>$rawDestGeneral,
|
||||
]);
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin([]);
|
||||
$generalID = Session::getGeneralID();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$rawList = Util::convertArrayToDict($db->query('SELECT no, name, npc, nation FROM general'), 'no');
|
||||
$nationID = $rawList[$generalID]['nation'];
|
||||
|
||||
|
||||
$result = [
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'nationID'=>$nationID,
|
||||
'generalID'=>$generalID,
|
||||
'column'=>['no', 'name', 'npc']
|
||||
];
|
||||
|
||||
$resultItem = [];
|
||||
foreach(Util::arrayGroupBy($rawList, 'nation') as $subNationID=>$generals){
|
||||
$subNation = [];
|
||||
foreach($generals as $general){
|
||||
$subNation[] = [$general['no'], $general['name'], $general['npc']];
|
||||
}
|
||||
$resultItem[$subNationID] = $subNation;
|
||||
}
|
||||
|
||||
$result['list'] = $resultItem;
|
||||
$result['nation'] = Util::convertArrayToDict($db->query('SELECT nation, name, color FROM nation'), 'nation');
|
||||
Json::die($result);
|
||||
+109
-109
@@ -1,109 +1,109 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireLogin();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$withToken = Util::getPost('with_token', 'bool', false);
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
if($session->isGameLoggedIn()){
|
||||
increaseRefresh("장수일람", 2);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
|
||||
$con = checkLimit($me['con']);
|
||||
if ($con >= 2) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$availableNextCall = $session->availableNextCallGetGeneralList??'2000-01-01 00:00:00';
|
||||
$now = new \DateTimeImmutable();
|
||||
|
||||
if($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 5){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>"장수 리스트는 10초에 한번 갱신 가능합니다.\n다음 시간 : ".$availableNextCall
|
||||
]);
|
||||
}
|
||||
|
||||
$availableNextCall = $now->add(new \DateInterval('PT10S'))->format('Y-m-d H:i:s');
|
||||
$session->availableNextCallGetGeneralList = $availableNextCall;
|
||||
}
|
||||
|
||||
$session->setReadOnly();
|
||||
|
||||
$rawGeneralList = $db->queryAllLists('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general');
|
||||
|
||||
$ownerNameList = [];
|
||||
if($gameStor->isunited){
|
||||
foreach(RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]){
|
||||
$ownerNameList[$ownerID] = $ownerName;
|
||||
}
|
||||
}
|
||||
|
||||
$generalList = [];
|
||||
foreach($rawGeneralList as $rawGeneral){
|
||||
[$owner,$no,$picture,$imgsvr,$npc,$age,$nation,$special,$special2,$personal,$name,$ownerName,$injury,$leadership,$strength,$intel,$experience,$dedication,$officerLevel,$killturn,$connectCnt] = $rawGeneral;
|
||||
|
||||
if(key_exists($owner, $ownerNameList)){
|
||||
$ownerName = $ownerNameList[$owner];
|
||||
}
|
||||
|
||||
$nationArr = getNationStaticInfo($nation);
|
||||
$lbonus = calcLeadershipBonus($officerLevel, $nationArr['level']);
|
||||
|
||||
$generalList[] = [
|
||||
$no,
|
||||
$picture,
|
||||
$imgsvr,
|
||||
$npc,
|
||||
$age,
|
||||
$nationArr['name'],
|
||||
getGeneralSpecialDomesticName($special),
|
||||
getGeneralSpecialWarName($special2),
|
||||
getGenChar($personal),
|
||||
$name,
|
||||
$npc==1?$ownerName:null,
|
||||
$injury,
|
||||
$leadership,
|
||||
$lbonus,
|
||||
$strength,
|
||||
$intel,
|
||||
getExpLevel($experience),
|
||||
getHonor($experience),
|
||||
getDed($dedication),
|
||||
getOfficerLevelText($officerLevel, $nationArr['level']),
|
||||
$killturn,
|
||||
$connectCnt
|
||||
];
|
||||
}
|
||||
|
||||
$result = [
|
||||
'result'=>'true',
|
||||
'list'=>$generalList,
|
||||
];
|
||||
|
||||
if($withToken){
|
||||
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
|
||||
$tokens = [];
|
||||
foreach($db->query('SELECT * FROM select_npc_token WHERE `valid_until`>=%s', $now) as $token){
|
||||
$validUntil = $token['valid_until'];
|
||||
|
||||
foreach(Json::decode($token['pick_result']) as $pickResult){
|
||||
$tokens[$pickResult['no']]=$pickResult['keepCnt'];
|
||||
}
|
||||
}
|
||||
$result['token'] = $tokens;
|
||||
}
|
||||
|
||||
Json::die($result);
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireLogin([]);
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$withToken = Util::getPost('with_token', 'bool', false);
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
if($session->isGameLoggedIn()){
|
||||
increaseRefresh("장수일람", 2);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID);
|
||||
$con = checkLimit($me['con']);
|
||||
if ($con >= 2) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'접속 제한중입니다. 1턴 이내에 너무 많은 갱신을 하셨습니다.'
|
||||
]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
$availableNextCall = $session->availableNextCallGetGeneralList??'2000-01-01 00:00:00';
|
||||
$now = new \DateTimeImmutable();
|
||||
|
||||
if($now <= new \DateTimeImmutable($availableNextCall) && $session->userGrade < 5){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>"장수 리스트는 10초에 한번 갱신 가능합니다.\n다음 시간 : ".$availableNextCall
|
||||
]);
|
||||
}
|
||||
|
||||
$availableNextCall = $now->add(new \DateInterval('PT10S'))->format('Y-m-d H:i:s');
|
||||
$session->availableNextCallGetGeneralList = $availableNextCall;
|
||||
}
|
||||
|
||||
$session->setReadOnly();
|
||||
|
||||
$rawGeneralList = $db->queryAllLists('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,owner_name as ownerName,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general');
|
||||
|
||||
$ownerNameList = [];
|
||||
if($gameStor->isunited){
|
||||
foreach(RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]){
|
||||
$ownerNameList[$ownerID] = $ownerName;
|
||||
}
|
||||
}
|
||||
|
||||
$generalList = [];
|
||||
foreach($rawGeneralList as $rawGeneral){
|
||||
[$owner,$no,$picture,$imgsvr,$npc,$age,$nation,$special,$special2,$personal,$name,$ownerName,$injury,$leadership,$strength,$intel,$experience,$dedication,$officerLevel,$killturn,$connectCnt] = $rawGeneral;
|
||||
|
||||
if(key_exists($owner, $ownerNameList)){
|
||||
$ownerName = $ownerNameList[$owner];
|
||||
}
|
||||
|
||||
$nationArr = getNationStaticInfo($nation);
|
||||
$lbonus = calcLeadershipBonus($officerLevel, $nationArr['level']);
|
||||
|
||||
$generalList[] = [
|
||||
$no,
|
||||
$picture,
|
||||
$imgsvr,
|
||||
$npc,
|
||||
$age,
|
||||
$nationArr['name'],
|
||||
getGeneralSpecialDomesticName($special),
|
||||
getGeneralSpecialWarName($special2),
|
||||
getGenChar($personal),
|
||||
$name,
|
||||
$npc==1?$ownerName:null,
|
||||
$injury,
|
||||
$leadership,
|
||||
$lbonus,
|
||||
$strength,
|
||||
$intel,
|
||||
getExpLevel($experience),
|
||||
getHonor($experience),
|
||||
getDed($dedication),
|
||||
getOfficerLevelText($officerLevel, $nationArr['level']),
|
||||
$killturn,
|
||||
$connectCnt
|
||||
];
|
||||
}
|
||||
|
||||
$result = [
|
||||
'result'=>'true',
|
||||
'list'=>$generalList,
|
||||
];
|
||||
|
||||
if($withToken){
|
||||
$now = (new \DateTimeImmutable())->format('Y-m-d H:i:s');
|
||||
$tokens = [];
|
||||
foreach($db->query('SELECT * FROM select_npc_token WHERE `valid_until`>=%s', $now) as $token){
|
||||
$validUntil = $token['valid_until'];
|
||||
|
||||
foreach(Json::decode($token['pick_result']) as $pickResult){
|
||||
$tokens[$pickResult['no']]=$pickResult['keepCnt'];
|
||||
}
|
||||
}
|
||||
$result['token'] = $tokens;
|
||||
}
|
||||
|
||||
Json::die($result);
|
||||
|
||||
@@ -157,6 +157,7 @@ foreach ($customViewColumns as $column => $reqPermission) {
|
||||
$resultColumns[] = $column;
|
||||
}
|
||||
|
||||
$generalList = [];
|
||||
foreach ($rawGeneralList as $rawGeneral) {
|
||||
//General 생성?
|
||||
|
||||
|
||||
@@ -21,9 +21,11 @@ foreach($rawTurn as [$turn_idx, $action, $arg, $brief]){
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
[$turnTerm, $year, $month, $lastExecute] = $gameStor->getValuesAsArray(['turnterm', 'year', 'month', 'turntime']);
|
||||
|
||||
$turnTime = $db->queryFirstField('SELECT turntime FROM general WHERE no=%i', $generalID);
|
||||
[$turnTime, $rawGeneralAux] = $db->queryFirstList('SELECT turntime, aux FROM general WHERE no=%i', $generalID);
|
||||
$generalAux = Json::decode($rawGeneralAux??'{}');
|
||||
|
||||
if(cutTurn($turnTime, $turnTerm) > cutTurn($lastExecute, $turnTerm)){
|
||||
//이미 이번달에 실행된 턴이다.
|
||||
@@ -42,5 +44,6 @@ Json::die([
|
||||
'year'=>$year,
|
||||
'month'=>$month,
|
||||
'date'=>TimeUtil::now(true),
|
||||
'turn'=>$commandList
|
||||
'turn'=>$commandList,
|
||||
'autorun_limit'=> $generalAux['autorun_limit']??null,
|
||||
]);
|
||||
@@ -37,7 +37,7 @@ list(
|
||||
$npcmode
|
||||
) = $gameStor->getValuesAsArray(['maxgeneral', 'turnterm', 'npcmode']);
|
||||
|
||||
if(!$npcmode){
|
||||
if($npcmode!=1){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'빙의 가능한 서버가 아닙니다'
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
function sortTokens(&$tokens){
|
||||
usort($tokens, function($lhs, $rhs){
|
||||
return array_sum($lhs['dex'])<=>array_sum($rhs['dex']);
|
||||
});
|
||||
}
|
||||
|
||||
function putInfoText(&$info){
|
||||
if(key_exists('specialDomestic', $info)){
|
||||
$class = buildGeneralSpecialDomesticClass($info['specialDomestic']);
|
||||
$info['specialDomesticName'] = $class->getName();
|
||||
$info['specialDomesticInfo'] = $class->getInfo();
|
||||
}
|
||||
|
||||
if(key_exists('specialWar', $info)){
|
||||
$class = buildGeneralSpecialDomesticClass($info['specialWar']);
|
||||
$info['specialWarName'] = $class->getName();
|
||||
$info['specialWarInfo'] = $class->getInfo();
|
||||
}
|
||||
}
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$oNow = new \DateTimeImmutable();
|
||||
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$npcmode = $gameStor->getValue('npcmode');
|
||||
if($npcmode!=2){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'선택 가능한 서버가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
$rawGeneral = $db->queryFirstRow('SELECT no, aux FROM general WHERE `owner` = %i', $userID);
|
||||
if($rawGeneral){
|
||||
$generalAux = Json::decode($rawGeneral['aux']);
|
||||
if(key_exists('next_change', $generalAux)&& $generalAux['next_change'] > $now){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'아직 다시 고를 수 없습니다'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$tokens = $db->query('SELECT unique_name, reserved_until, info FROM `select_pool` WHERE `owner`=%i AND `reserved_until`>=%s', $userID, $now);
|
||||
|
||||
if($tokens){
|
||||
$pick = [];
|
||||
$valid_until = null;
|
||||
$specialInfo = [];
|
||||
foreach($tokens as $token){
|
||||
$valid_until = $token['reserved_until'];
|
||||
$info = Json::decode($token['info']);
|
||||
putInfoText($info);
|
||||
$info['uniqueName'] = $token['unique_name'];
|
||||
$pick[] = $info;
|
||||
}
|
||||
sortTokens($pick);//좀 무식하지만..
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>$pick,
|
||||
'validUntil'=>$valid_until
|
||||
]);
|
||||
}
|
||||
|
||||
$pick = [];
|
||||
$valid_until = null;
|
||||
foreach(pickGeneralFromPool($db, $userID, 14) as $pickObj){
|
||||
$valid_until = $pickObj->getValidUntil();
|
||||
$info = $pickObj->getInfo();
|
||||
putInfoText($info);
|
||||
$pick[] = $info;
|
||||
}
|
||||
sortTokens($pick);//좀 무식하지만..
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'pick'=>$pick,
|
||||
'validUntil'=>$valid_until
|
||||
]);
|
||||
+214
-208
@@ -1,209 +1,215 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
|
||||
if(!class_exists('\\sammo\\DB')){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'DB리셋 필요'
|
||||
]);
|
||||
}
|
||||
|
||||
$serverName = DB::prefix();
|
||||
$serverAcl = $session->acl[$serverName]??[];
|
||||
$allowReset = in_array('reset', $serverAcl);
|
||||
$allowFullReset = in_array('fullReset',$serverAcl);
|
||||
$allowReset |= $allowFullReset;
|
||||
|
||||
$reserve_open = Util::getPost('reserve_open');
|
||||
if($reserve_open && $reserve_open < date('Y-m-d H:i')){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'현재 시간보다 이전 시간대를 예약 시간으로 지정했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$pre_reserve_open = Util::getPost('pre_reserve_open');
|
||||
if($pre_reserve_open && !$reserve_open){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'가오픈 예약을 위해선 오픈 예약을 지정해야합니다.'
|
||||
]);
|
||||
}
|
||||
if($pre_reserve_open && $pre_reserve_open >= $reserve_open){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'가오픈 시간이 오픈 예약 시점보다 이전이어야 합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($session->userGrade < 5 && !$allowReset){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'관리자 아님'
|
||||
]);
|
||||
}
|
||||
|
||||
$v = new Validator($_POST);
|
||||
$v->rule('required', [
|
||||
'turnterm',
|
||||
'sync',
|
||||
'scenario',
|
||||
'fiction',
|
||||
'extend',
|
||||
'join_mode',
|
||||
'npcmode',
|
||||
'show_img_level',
|
||||
'autorun_user_minutes'
|
||||
])->rule('integer', [
|
||||
'turnterm',
|
||||
'sync',
|
||||
'scenario',
|
||||
'fiction',
|
||||
'extend',
|
||||
'npcmode',
|
||||
'show_img_level',
|
||||
'tournament_trig',
|
||||
'autorun_user_minutes'
|
||||
])->rule('in', 'join_mode', ['onlyRandom', 'full']);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$allowReset = true;
|
||||
if($session->userGrade < 5 && !$allowFullReset){
|
||||
//리셋 가능한 조건인지 테스트
|
||||
$allowReset = false;
|
||||
|
||||
if(file_exists(__DIR__.'/.htaccess')){
|
||||
$allowReset = true;
|
||||
}
|
||||
else{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
if($gameStor->isunited){
|
||||
$allowReset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$allowReset){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부족한 권한: 서버가 닫혀있거나, 천통되어 있을 경우에만 리셋 가능합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$turnterm = (int)$_POST['turnterm'];
|
||||
$sync = (int)$_POST['sync'];
|
||||
$scenario = (int)$_POST['scenario'];
|
||||
$fiction = (int)$_POST['fiction'];
|
||||
$extend = (int)$_POST['extend'];
|
||||
$npcmode = (int)$_POST['npcmode'];
|
||||
$show_img_level = (int)$_POST['show_img_level'];
|
||||
$tournament_trig = (int)$_POST['tournament_trig'];
|
||||
$join_mode = $_POST['join_mode'];
|
||||
$autorun_user_minutes = (int)$_POST['autorun_user_minutes'];
|
||||
$autorun_user_options = [];
|
||||
foreach(Util::getPost('autorun_user', 'array_string', []) as $autorun_option){
|
||||
$autorun_user_options[$autorun_option] = 1;
|
||||
}
|
||||
|
||||
if($autorun_user_minutes > 0 && !$autorun_user_options){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'적어도 자동 행동 중 하나는 선택을 해야합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($autorun_user_minutes < 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'자동 행동 기한이 0보다 작을 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$autorun_user = $autorun_user_minutes?[
|
||||
'limit_minutes'=>$autorun_user_minutes,
|
||||
'options'=>$autorun_user_options
|
||||
]:null;
|
||||
|
||||
if($reserve_open){
|
||||
$reserve_open = new \DateTime($reserve_open);
|
||||
$db = DB::db();
|
||||
|
||||
if (!$db->queryFirstField("SHOW TABLES LIKE 'storage'")) {
|
||||
$clearResult = ResetHelper::clearDB();
|
||||
if(!$clearResult['result']){
|
||||
Json::die($clearResult);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$db->queryFirstField("SHOW TABLES LIKE 'reserved_open'")) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'예약 테이블이 없음!'
|
||||
]);
|
||||
}
|
||||
|
||||
$scenarioObj = new Scenario($scenario, true);
|
||||
$open_date = $reserve_open->format('Y-m-d H:i:s');
|
||||
|
||||
$reserveInfo = [
|
||||
'turnterm'=>$turnterm,
|
||||
'sync'=>$sync,
|
||||
'scenario'=>$scenario,
|
||||
'scenarioName'=>$scenarioObj->getTitle(),
|
||||
'fiction'=>$fiction,
|
||||
'extend'=>$extend,
|
||||
'npcmode'=>$npcmode,
|
||||
'show_img_level'=>$show_img_level,
|
||||
'tournament_trig'=>$tournament_trig,
|
||||
'gameConf'=>$scenarioObj->getGameConf(),
|
||||
'join_mode'=>$join_mode,
|
||||
'starttime'=>$open_date,
|
||||
'autorun_user'=>$autorun_user
|
||||
];
|
||||
|
||||
|
||||
if($pre_reserve_open){
|
||||
$pre_reserve_open = new \DateTime($pre_reserve_open);
|
||||
$open_date = $pre_reserve_open->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
|
||||
|
||||
$db->delete('reserved_open', true);
|
||||
$db->insert('reserved_open', [
|
||||
'options'=>Json::encode($reserveInfo),
|
||||
'date'=>$open_date
|
||||
]);
|
||||
AppConf::getList()[DB::prefix()]->closeServer();
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'예약'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die(ResetHelper::buildScenario(
|
||||
$turnterm,
|
||||
$sync,
|
||||
$scenario,
|
||||
$fiction,
|
||||
$extend,
|
||||
$npcmode,
|
||||
$show_img_level,
|
||||
$tournament_trig,
|
||||
$join_mode,
|
||||
TimeUtil::now(),
|
||||
$autorun_user
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
|
||||
if(!class_exists('\\sammo\\DB')){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'DB리셋 필요'
|
||||
]);
|
||||
}
|
||||
|
||||
$serverName = DB::prefix();
|
||||
$serverAcl = $session->acl[$serverName]??[];
|
||||
$allowReset = in_array('reset', $serverAcl);
|
||||
$allowFullReset = in_array('fullReset',$serverAcl);
|
||||
$allowReset = $allowReset || $allowFullReset;
|
||||
|
||||
$reserve_open = Util::getPost('reserve_open');
|
||||
if($reserve_open && $reserve_open < date('Y-m-d H:i')){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'현재 시간보다 이전 시간대를 예약 시간으로 지정했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$pre_reserve_open = Util::getPost('pre_reserve_open');
|
||||
if($pre_reserve_open && !$reserve_open){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'가오픈 예약을 위해선 오픈 예약을 지정해야합니다.'
|
||||
]);
|
||||
}
|
||||
if($pre_reserve_open && $pre_reserve_open >= $reserve_open){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'가오픈 시간이 오픈 예약 시점보다 이전이어야 합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($session->userGrade < 5 && !$allowReset){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'관리자 아님'
|
||||
]);
|
||||
}
|
||||
|
||||
$v = new Validator($_POST);
|
||||
$v->rule('required', [
|
||||
'turnterm',
|
||||
'sync',
|
||||
'scenario',
|
||||
'fiction',
|
||||
'extend',
|
||||
'block_general_create',
|
||||
'join_mode',
|
||||
'npcmode',
|
||||
'show_img_level',
|
||||
'autorun_user_minutes'
|
||||
])->rule('integer', [
|
||||
'turnterm',
|
||||
'sync',
|
||||
'scenario',
|
||||
'fiction',
|
||||
'extend',
|
||||
'block_general_create',
|
||||
'npcmode',
|
||||
'show_img_level',
|
||||
'tournament_trig',
|
||||
'autorun_user_minutes'
|
||||
])->rule('in', 'join_mode', ['onlyRandom', 'full']);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$allowReset = true;
|
||||
if($session->userGrade < 5 && !$allowFullReset){
|
||||
//리셋 가능한 조건인지 테스트
|
||||
$allowReset = false;
|
||||
|
||||
if(file_exists(__DIR__.'/.htaccess')){
|
||||
$allowReset = true;
|
||||
}
|
||||
else{
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
if($gameStor->isunited){
|
||||
$allowReset = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$allowReset){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부족한 권한: 서버가 닫혀있거나, 천통되어 있을 경우에만 리셋 가능합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$turnterm = (int)$_POST['turnterm'];
|
||||
$sync = (int)$_POST['sync'];
|
||||
$scenario = (int)$_POST['scenario'];
|
||||
$fiction = (int)$_POST['fiction'];
|
||||
$extend = (int)$_POST['extend'];
|
||||
$npcmode = (int)$_POST['npcmode'];
|
||||
$block_general_create = (bool)$_POST['block_general_create'];
|
||||
$show_img_level = (int)$_POST['show_img_level'];
|
||||
$tournament_trig = (int)$_POST['tournament_trig'];
|
||||
$join_mode = $_POST['join_mode'];
|
||||
$autorun_user_minutes = (int)$_POST['autorun_user_minutes'];
|
||||
$autorun_user_options = [];
|
||||
|
||||
foreach(Util::getPost('autorun_user', 'array_string', []) as $autorun_option){
|
||||
$autorun_user_options[$autorun_option] = 1;
|
||||
}
|
||||
|
||||
if($autorun_user_minutes > 0 && !$autorun_user_options){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'적어도 자동 행동 중 하나는 선택을 해야합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($autorun_user_minutes < 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'자동 행동 기한이 0보다 작을 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$autorun_user = $autorun_user_minutes?[
|
||||
'limit_minutes'=>$autorun_user_minutes,
|
||||
'options'=>$autorun_user_options
|
||||
]:null;
|
||||
|
||||
if($reserve_open){
|
||||
$reserve_open = new \DateTime($reserve_open);
|
||||
$db = DB::db();
|
||||
|
||||
if (!$db->queryFirstField("SHOW TABLES LIKE 'storage'")) {
|
||||
$clearResult = ResetHelper::clearDB();
|
||||
if(!$clearResult['result']){
|
||||
Json::die($clearResult);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$db->queryFirstField("SHOW TABLES LIKE 'reserved_open'")) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'예약 테이블이 없음!'
|
||||
]);
|
||||
}
|
||||
|
||||
$scenarioObj = new Scenario($scenario, true);
|
||||
$open_date = $reserve_open->format('Y-m-d H:i:s');
|
||||
|
||||
$reserveInfo = [
|
||||
'turnterm'=>$turnterm,
|
||||
'sync'=>$sync,
|
||||
'scenario'=>$scenario,
|
||||
'scenarioName'=>$scenarioObj->getTitle(),
|
||||
'fiction'=>$fiction,
|
||||
'extend'=>$extend,
|
||||
'block_general_create'=>$block_general_create,
|
||||
'npcmode'=>$npcmode,
|
||||
'show_img_level'=>$show_img_level,
|
||||
'tournament_trig'=>$tournament_trig,
|
||||
'gameConf'=>$scenarioObj->getGameConf(),
|
||||
'join_mode'=>$join_mode,
|
||||
'starttime'=>$open_date,
|
||||
'autorun_user'=>$autorun_user
|
||||
];
|
||||
|
||||
|
||||
if($pre_reserve_open){
|
||||
$pre_reserve_open = new \DateTime($pre_reserve_open);
|
||||
$open_date = $pre_reserve_open->format('Y-m-d H:i:s');
|
||||
}
|
||||
|
||||
|
||||
|
||||
$db->delete('reserved_open', true);
|
||||
$db->insert('reserved_open', [
|
||||
'options'=>Json::encode($reserveInfo),
|
||||
'date'=>$open_date
|
||||
]);
|
||||
ServConfig::getServerList()[DB::prefix()]->closeServer();
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'예약'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die(ResetHelper::buildScenario(
|
||||
$turnterm,
|
||||
$sync,
|
||||
$scenario,
|
||||
$fiction,
|
||||
$extend,
|
||||
$block_general_create,
|
||||
$npcmode,
|
||||
$show_img_level,
|
||||
$tournament_trig,
|
||||
$join_mode,
|
||||
TimeUtil::now(),
|
||||
$autorun_user
|
||||
));
|
||||
+102
-102
@@ -1,103 +1,103 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
if($session->userGrade < 6){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'관리자 아님'
|
||||
]);
|
||||
}
|
||||
|
||||
$fullReset = Util::getPost('full_reset', 'bool', false);
|
||||
$host = Util::getPost('db_host');
|
||||
$port = Util::getPost('db_port', 'int');
|
||||
$username = Util::getPost('db_id');
|
||||
$password = Util::getPost('db_pw');
|
||||
$dbName = Util::getPost('db_name');
|
||||
|
||||
if(!$host || !$port || !$username || !$password || !$dbName){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'입력 값이 올바르지 않습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if($fullReset && class_exists('\\sammo\\DB')){
|
||||
$mysqli_obj = DB::db()->get();
|
||||
|
||||
if($mysqli_obj->multi_query(file_get_contents(__DIR__.'/sql/reset.sql'))){
|
||||
while(true){
|
||||
if (!$mysqli_obj->more_results()) {
|
||||
break;
|
||||
}
|
||||
if(!$mysqli_obj->next_result()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($fullReset){
|
||||
FileUtil::delInDir(__DIR__."/logs");
|
||||
FileUtil::delInDir(__DIR__."/data");
|
||||
if(file_exists(__DIR__.'/d_setting/DB.php')){
|
||||
@unlink(__DIR__.'/d_setting/DB.php');
|
||||
}
|
||||
if(file_exists(__DIR__.'/d_setting/UniqueConst.php')){
|
||||
@unlink(__DIR__.'/d_setting/UniqueConst.php');
|
||||
}
|
||||
}
|
||||
|
||||
function dbConnFail($params){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'DB 접속에 실패했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$db = new \MeekroDB($host,$username,$password,$dbName,$port,'utf8mb4');
|
||||
$db->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
|
||||
|
||||
$db->throw_exception_on_nonsql_error = false;
|
||||
$db->nonsql_error_handler = 'dbConnFail';
|
||||
|
||||
|
||||
$mysqli_obj = $db->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨.
|
||||
|
||||
$prefix = basename(__DIR__);
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__.'/d_setting/DB.orig.php',
|
||||
__DIR__.'/d_setting/DB.php',[
|
||||
'host'=>$host,
|
||||
'user'=>$username,
|
||||
'password'=>$password,
|
||||
'dbName'=>$dbName,
|
||||
'port'=>$port,
|
||||
'prefix'=>$prefix
|
||||
], true
|
||||
);
|
||||
|
||||
|
||||
|
||||
if($result !== true){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
|
||||
ResetHelper::clearDB();
|
||||
|
||||
AppConf::getList()[$prefix]->closeServer();
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
if($session->userGrade < 6){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'관리자 아님'
|
||||
]);
|
||||
}
|
||||
|
||||
$fullReset = Util::getPost('full_reset', 'bool', false);
|
||||
$host = Util::getPost('db_host');
|
||||
$port = Util::getPost('db_port', 'int');
|
||||
$username = Util::getPost('db_id');
|
||||
$password = Util::getPost('db_pw');
|
||||
$dbName = Util::getPost('db_name');
|
||||
|
||||
if(!$host || !$port || !$username || !$password || !$dbName){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'입력 값이 올바르지 않습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
if($fullReset && class_exists('\\sammo\\DB')){
|
||||
$mysqli_obj = DB::db()->get();
|
||||
|
||||
if($mysqli_obj->multi_query(file_get_contents(__DIR__.'/sql/reset.sql'))){
|
||||
while(true){
|
||||
if (!$mysqli_obj->more_results()) {
|
||||
break;
|
||||
}
|
||||
if(!$mysqli_obj->next_result()){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($fullReset){
|
||||
FileUtil::delInDir(__DIR__."/logs");
|
||||
FileUtil::delInDir(__DIR__."/data");
|
||||
if(file_exists(__DIR__.'/d_setting/DB.php')){
|
||||
@unlink(__DIR__.'/d_setting/DB.php');
|
||||
}
|
||||
if(file_exists(__DIR__.'/d_setting/UniqueConst.php')){
|
||||
@unlink(__DIR__.'/d_setting/UniqueConst.php');
|
||||
}
|
||||
}
|
||||
|
||||
function dbConnFail($params){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'DB 접속에 실패했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$db = new \MeekroDB($host,$username,$password,$dbName,$port,'utf8mb4');
|
||||
$db->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
|
||||
|
||||
$db->throw_exception_on_nonsql_error = false;
|
||||
$db->nonsql_error_handler = 'dbConnFail';
|
||||
|
||||
|
||||
$mysqli_obj = $db->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨.
|
||||
|
||||
$prefix = basename(__DIR__);
|
||||
|
||||
$result = Util::generateFileUsingSimpleTemplate(
|
||||
__DIR__.'/d_setting/DB.orig.php',
|
||||
__DIR__.'/d_setting/DB.php',[
|
||||
'host'=>$host,
|
||||
'user'=>$username,
|
||||
'password'=>$password,
|
||||
'dbName'=>$dbName,
|
||||
'port'=>$port,
|
||||
'prefix'=>$prefix
|
||||
], true
|
||||
);
|
||||
|
||||
|
||||
|
||||
if($result !== true){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
|
||||
ResetHelper::clearDB();
|
||||
|
||||
ServConfig::getServerList()[$prefix]->closeServer();
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
@@ -9,7 +9,7 @@ $serverName = DB::prefix();
|
||||
$serverAcl = $session->acl[$serverName]??[];
|
||||
$allowReset = in_array('reset', $serverAcl);
|
||||
$allowFullReset = in_array('fullReset',$serverAcl);
|
||||
$allowReset |= $allowFullReset;
|
||||
$allowReset = $allowReset || $allowFullReset;
|
||||
|
||||
if($session->userGrade < 5 && !$allowReset){
|
||||
Json::die([
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
use Nette\Caching\Cache;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
if(!class_exists('\\sammo\\UniqueConst')){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'서버 초기화되지 않음'
|
||||
]);
|
||||
}
|
||||
|
||||
if(!prepareDir('data/file_cache')){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'cache 불가'
|
||||
]);
|
||||
}
|
||||
|
||||
$storage = new \Nette\Caching\Storages\FileStorage('data/file_cache');
|
||||
$cache = new Cache($storage);
|
||||
$serverID = UniqueConst::$serverID;
|
||||
|
||||
$mapInfo = $cache->load("recent_map");
|
||||
//로그인 검사
|
||||
|
||||
$now = time();
|
||||
|
||||
if($mapInfo && ($now - $mapInfo['timestamp'] < 600)){
|
||||
$mapEtag = $mapInfo['etag'];
|
||||
$mapModified = $mapInfo['timestamp'];
|
||||
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $mapModified)." GMT");
|
||||
header("Etag: $mapEtag");
|
||||
|
||||
if (
|
||||
strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']??'2000-01-01') === $mapModified ||
|
||||
trim($_SERVER['HTTP_IF_NONE_MATCH']??'') === $mapEtag
|
||||
) {
|
||||
header("HTTP/1.1 304 Not Modified");
|
||||
die();
|
||||
}
|
||||
|
||||
Json::die($mapInfo['data'], 0);
|
||||
}
|
||||
|
||||
$defaultPost = [
|
||||
'year' => null,
|
||||
'month' => null,
|
||||
'aux' => null,
|
||||
'neutralView' => true,
|
||||
'showMe' => false,
|
||||
];
|
||||
|
||||
$history = formatHistoryToHTML(getGlobalHistoryLogRecent(10));
|
||||
$rawMap = getWorldMap([
|
||||
'year' => null,
|
||||
'month' => null,
|
||||
'aux' => null,
|
||||
'neutralView' => true,
|
||||
'showMe' => false,
|
||||
]);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$mapTheme = $gameStor->map_theme ?? 'che';
|
||||
|
||||
$rawMap['history'] = $history;
|
||||
$rawMap['theme'] = $mapTheme;
|
||||
|
||||
$etag = hash('sha256', $serverID.$now);
|
||||
$map = [
|
||||
'etag'=>$etag,
|
||||
'timestamp'=>$now,
|
||||
'data'=>$rawMap,
|
||||
];
|
||||
$cache->save("recent_map", $map);
|
||||
header("Last-Modified: ".gmdate("D, d M Y H:i:s", $now)." GMT");
|
||||
header("Etag: $etag");
|
||||
|
||||
Json::die($map['data'], 0);
|
||||
@@ -56,6 +56,6 @@ else{
|
||||
|
||||
|
||||
Json::die([
|
||||
'result' => $result===DiplomaticMessage::ACCEPTED,
|
||||
'result' => $result!==DiplomaticMessage::INVALID,
|
||||
'reason' => $reason
|
||||
]);
|
||||
@@ -32,7 +32,7 @@ $lastMsgGet[] = TimeUtil::now();
|
||||
$session->lastMsgGet = Json::encode($lastMsgGet);
|
||||
|
||||
if($delayTime){
|
||||
sleep(0.2);
|
||||
usleep(200);
|
||||
}
|
||||
$session->setReadOnly();
|
||||
|
||||
|
||||
+360
-359
@@ -1,360 +1,361 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$action = Util::getPost('action');
|
||||
$officerLevel = Util::getPost('officerLevel', 'int');
|
||||
$destGeneralID = Util::getPost('destGeneralID', 'int');
|
||||
$destCityID = Util::getPost('destCityID', 'int');
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['startyear','year','month','scenario']);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no,nation,officer_level from general where owner=%i', $userID);
|
||||
$myOfficerLevel = $me['officer_level'];
|
||||
$nationID = $me['nation'];
|
||||
|
||||
//수뇌가 아니면 아무것도 할 수 없음
|
||||
if($myOfficerLevel < 5){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'수뇌가 아닙니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($action === '추방' && $destGeneralID==0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수가 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($destGeneralID==0){
|
||||
$general = new DummyGeneral(true);
|
||||
}
|
||||
else{
|
||||
$general = General::createGeneralObjFromDB($destGeneralID, [
|
||||
'name', 'leadership', 'strength', 'intel', 'gold','rice',
|
||||
'troop','officer_level','npc','picture','imgsvr',
|
||||
'permission','penalty','belong', 'crewtype',
|
||||
'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit',
|
||||
], 1);
|
||||
|
||||
if($general instanceof DummyGeneral){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 장수입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($nationID != $general->getNationID()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'아국 장수가 아닙니다'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if($officerLevel == 12){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'군주를 대상으로 할 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
function do수뇌임명(General $general, int $targetOfficerLevel):?string{
|
||||
$generalID = $general->getID();
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
[$chiefSet, $nationLevel] = $db->queryFirstList('SELECT chief_set,level FROM nation WHERE nation = %i',$nationID);
|
||||
|
||||
// 임명가능 레벨
|
||||
$lv = getNationChiefLevel($nationLevel);
|
||||
|
||||
if($targetOfficerLevel < $lv){
|
||||
return '임명불가능한 관직입니다.';
|
||||
}
|
||||
|
||||
if(isOfficerSet($chiefSet, $targetOfficerLevel)){
|
||||
return '지금은 임명할 수 없습니다.';
|
||||
}
|
||||
|
||||
//기존 장수 일반으로
|
||||
$db->update('general', [
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0,
|
||||
], 'nation=%i AND officer_level=%i AND no!=%i', $nationID, $targetOfficerLevel, $generalID);
|
||||
|
||||
if($targetOfficerLevel === 11){
|
||||
|
||||
}
|
||||
else if($targetOfficerLevel % 2 == 0){
|
||||
if($general->getVar('strength') < GameConst::$chiefStatMin){
|
||||
return '무력이 부족합니다.';
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
if($general->getVar('intel') < GameConst::$chiefStatMin){
|
||||
return '지력이 부족합니다.';
|
||||
}
|
||||
}
|
||||
|
||||
//신임 장수
|
||||
$general->setVar('officer_level', $targetOfficerLevel);
|
||||
$general->setVar('officer_city', 0);
|
||||
$db->update('nation', [
|
||||
'chief_set'=> $db->sqleval('chief_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
], 'nation=%i', $nationID);
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function do도시임명(General $general, int $cityID, int $targetOfficerLevel):?string{
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
if(CityConst::byID($cityID) === null){
|
||||
return '올바르지 않은 도시입니다';
|
||||
}
|
||||
|
||||
$officerSet = $db->queryFirstField('SELECT officer_set FROM city WHERE nation=%i AND city=%i', $nationID, $cityID);
|
||||
if($officerSet === null){
|
||||
return '아국 도시가 아닙니다';
|
||||
}
|
||||
|
||||
if(isOfficerSet($officerSet, $targetOfficerLevel)){
|
||||
return '이미 다른 장수가 임명되어있습니다';
|
||||
}
|
||||
|
||||
//기존 장수 일반으로
|
||||
$db->update('general', [
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0,
|
||||
], 'officer_level=%i AND officer_city=%i AND no!=%i', $targetOfficerLevel, $cityID, $general->getID());
|
||||
|
||||
if($general instanceof DummyGeneral){
|
||||
return null;
|
||||
}
|
||||
|
||||
if($targetOfficerLevel === 4 && $general->getVar('strength') < GameConst::$chiefStatMin){
|
||||
return '무력이 부족합니다.';
|
||||
}
|
||||
|
||||
if($targetOfficerLevel === 3 && $general->getVar('intel') < GameConst::$chiefStatMin){
|
||||
return '지력이 부족합니다.';
|
||||
}
|
||||
|
||||
//신임 장수
|
||||
$db->update('city', [
|
||||
'officer_set'=>$db->sqleval('officer_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
], 'city=%i AND nation=%i', $cityID, $nationID);
|
||||
$general->setVar('officer_level', $targetOfficerLevel);
|
||||
$general->setVar('officer_city', $cityID);
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function do추방(General $general, int $myOfficerLevel):?string{
|
||||
$generalID = $general->getID();
|
||||
$generalName = $general->getVar('name');
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
|
||||
|
||||
//추방할사람이 외교권자이면 불가
|
||||
$permission = checkSecretPermission($general->getRaw());
|
||||
if($permission == 4){
|
||||
return '외교권자는 추방할 수 없습니다.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getValues(['startyear','year','month','scenario']);
|
||||
|
||||
$nation = $db->queryFirstRow('SELECT name,chief_set,color FROM nation WHERE nation=%i', $nationID);
|
||||
$nationName = $nation['name'];
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
//이미 지정했다면 무시
|
||||
if(isOfficerSet($nation['chief_set'], $myOfficerLevel) || ($myOfficerLevel == 0 && $myOfficerLevel == 12)) {
|
||||
return '이미 추방 권한을 사용했습니다.';
|
||||
}
|
||||
$gold = 0;
|
||||
$rice = 0;
|
||||
// 금쌀1000이상은 남김
|
||||
if($general->getVar('gold') > GameConst::$defaultGold) {
|
||||
$gold = $general->getVar('gold') - GameConst::$defaultGold;
|
||||
$general->setVar('gold', GameConst::$defaultGold);
|
||||
}
|
||||
if($general->getVar('rice') > GameConst::$defaultRice) {
|
||||
$rice = $general->getVar('rice') - GameConst::$defaultRice;
|
||||
$general->setVar('rice', GameConst::$defaultRice);
|
||||
}
|
||||
|
||||
$general->setVar('nation', 0);
|
||||
$general->setVar('officer_level', 0);
|
||||
$general->setVar('officer_city', 0);
|
||||
$general->setVar('belong', 0);
|
||||
$oldMakeLimit = $general->getVar('makelimit');
|
||||
$general->setVar('makelimit', 12);
|
||||
$general->setVar('permission', 'normal');
|
||||
|
||||
$josaYi = JosaUtil::pick($generalName, '이');
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <D><b>{$nationName}</b></>에서 <R>추방</>당했습니다.");
|
||||
$logger->pushGeneralActionLog("<D><b>{$nationName}</b></>에서 <R>추방</>당했습니다.", ActionLogger::PLAIN);
|
||||
|
||||
// 명성/공헌 N*10%감소
|
||||
if($env['year'] <= $env['startyear'] && $general->getNPCType() < 2){
|
||||
$general->setVar('makelimit', $oldMakeLimit);
|
||||
}
|
||||
else{
|
||||
$betrayCnt = $general->getVar('betray');
|
||||
$general->addExperience(-$general->getVar('experience')*0.1*$betrayCnt);
|
||||
$general->addDedication(-$general->getVar('dedication')*0.1*$betrayCnt);
|
||||
$general->increaseVarWithLimit('betray', 1, null, GameConst::$maxBetrayCnt);
|
||||
}
|
||||
|
||||
//부대장일 경우
|
||||
if($general->getVar('troop') == $generalID){
|
||||
// 모두 탈퇴
|
||||
$db->update('general', [
|
||||
'troop'=>0,
|
||||
], 'troop = %i', $generalID);
|
||||
$db->delete('troop', 'troop_leader=%i', $generalID);
|
||||
}
|
||||
$general->setVar('troop', 0);
|
||||
|
||||
if($general->getNPCType() >= 2 && ($env['scenario'] < 100 || Util::randBool(0.01))) {
|
||||
|
||||
$str = Util::choiceRandom([
|
||||
'날 버리다니... 곧 전장에서 복수해주겠다...',
|
||||
'추방이라... 내가 무얼 잘못했단 말인가...',
|
||||
'어디 추방해가면서 잘되나 보자... 꼭 복수하겠다...',
|
||||
'인덕이 제일이거늘... 추방이 웬말인가... 저주한다!',
|
||||
'날 추방했으니 그 복수로 적국에 정보를 팔아 넘겨야겠군요. 그럼 이만.'
|
||||
]);
|
||||
|
||||
$src = new MessageTarget(
|
||||
$generalID,
|
||||
$generalName,
|
||||
$nationID,
|
||||
$nation['name'],
|
||||
$nation['color'],
|
||||
GetImageURL($general->getVar('imgsvr'), $general->getVar('picture'))
|
||||
);
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PUBLIC,
|
||||
$src,
|
||||
$src,
|
||||
$str,
|
||||
new \DateTime(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
$msg->send();
|
||||
}
|
||||
|
||||
if($env['year'] < $env['startyear']+3) {
|
||||
//초반엔 군주 부상 증가(엔장 임관지양)
|
||||
$db->update('general', [
|
||||
'injury'=>$db->sqleval('least(injury + 1, %i)', 80),
|
||||
], 'nation=%i AND officer_level=12', $nationID);
|
||||
|
||||
$db->update('nation', [
|
||||
'gennum'=>$db->sqleval('gennum - %i', $general->getNPCType()!=5?1:0),
|
||||
'gold'=>$db->sqleval('gold + %i', $gold),
|
||||
'rice'=>$db->sqleval('rice + %i', $rice),
|
||||
], 'nation = %i', $nationID);
|
||||
} else {
|
||||
//이번분기는 추방불가(초반 제외)
|
||||
$db->update('nation', [
|
||||
'chief_set'=>$db->sqleval('chief_set | %i', doOfficerSet(0, $myOfficerLevel)),
|
||||
'gennum'=>$db->sqleval('gennum - %i', $general->getNPCType()!=5?1:0),
|
||||
'gold'=>$db->sqleval('gold + %i', $gold),
|
||||
'rice'=>$db->sqleval('rice + %i', $rice),
|
||||
], 'nation = %i', $nationID);
|
||||
}
|
||||
|
||||
$logger->pushGeneralHistoryLog("<D>{$nation['name']}</>에서 추방됨");
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if($action == "임명") {
|
||||
if(2 <= $officerLevel && $officerLevel <= 4){
|
||||
if(!$destCityID){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'도시가 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
$result = do도시임명($general, $destCityID, $officerLevel);
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
if(5 <= $officerLevel && $officerLevel < 12){
|
||||
$result = do수뇌임명($general, $officerLevel);
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 지정입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($action == "추방") {
|
||||
$result = do추방($general, $myOfficerLevel);
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 명령입니다.'
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$action = Util::getPost('action');
|
||||
$officerLevel = Util::getPost('officerLevel', 'int');
|
||||
$destGeneralID = Util::getPost('destGeneralID', 'int');
|
||||
$destCityID = Util::getPost('destCityID', 'int');
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin()->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['startyear','year','month','scenario']);
|
||||
|
||||
$me = $db->queryFirstRow('SELECT no,nation,officer_level from general where owner=%i', $userID);
|
||||
$myOfficerLevel = $me['officer_level'];
|
||||
$nationID = $me['nation'];
|
||||
|
||||
//수뇌가 아니면 아무것도 할 수 없음
|
||||
if($myOfficerLevel < 5){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'수뇌가 아닙니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($action === '추방' && $destGeneralID==0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수가 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($destGeneralID==0){
|
||||
$general = new DummyGeneral(true);
|
||||
$general->setVar('nation', $nationID);
|
||||
}
|
||||
else{
|
||||
$general = General::createGeneralObjFromDB($destGeneralID, [
|
||||
'name', 'leadership', 'strength', 'intel', 'gold','rice',
|
||||
'troop','officer_level','npc','picture','imgsvr',
|
||||
'permission','penalty','belong', 'crewtype',
|
||||
'experience', 'dedication', 'betray', 'dedlevel', 'explevel', 'makelimit', 'aux',
|
||||
], 1);
|
||||
|
||||
if($general instanceof DummyGeneral){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 장수입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($nationID != $general->getNationID()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'아국 장수가 아닙니다'
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
if($officerLevel == 12){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'군주를 대상으로 할 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
function do수뇌임명(General $general, int $targetOfficerLevel):?string{
|
||||
$generalID = $general->getID();
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
[$chiefSet, $nationLevel] = $db->queryFirstList('SELECT chief_set,level FROM nation WHERE nation = %i',$nationID);
|
||||
|
||||
// 임명가능 레벨
|
||||
$lv = getNationChiefLevel($nationLevel);
|
||||
|
||||
if($targetOfficerLevel < $lv){
|
||||
return '임명불가능한 관직입니다.';
|
||||
}
|
||||
|
||||
if(isOfficerSet($chiefSet, $targetOfficerLevel)){
|
||||
return '지금은 임명할 수 없습니다.';
|
||||
}
|
||||
|
||||
//기존 장수 일반으로
|
||||
$db->update('general', [
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0,
|
||||
], 'nation=%i AND officer_level=%i AND no!=%i', $nationID, $targetOfficerLevel, $generalID);
|
||||
|
||||
if($targetOfficerLevel === 11){
|
||||
|
||||
}
|
||||
else if($targetOfficerLevel % 2 == 0){
|
||||
if($general->getVar('strength') < GameConst::$chiefStatMin){
|
||||
return '무력이 부족합니다.';
|
||||
}
|
||||
|
||||
}
|
||||
else{
|
||||
if($general->getVar('intel') < GameConst::$chiefStatMin){
|
||||
return '지력이 부족합니다.';
|
||||
}
|
||||
}
|
||||
|
||||
//신임 장수
|
||||
$general->setVar('officer_level', $targetOfficerLevel);
|
||||
$general->setVar('officer_city', 0);
|
||||
$db->update('nation', [
|
||||
'chief_set'=> $db->sqleval('chief_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
], 'nation=%i', $nationID);
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function do도시임명(General $general, int $cityID, int $targetOfficerLevel):?string{
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
if(CityConst::byID($cityID) === null){
|
||||
return '올바르지 않은 도시입니다';
|
||||
}
|
||||
|
||||
$officerSet = $db->queryFirstField('SELECT officer_set FROM city WHERE nation=%i AND city=%i', $nationID, $cityID);
|
||||
if($officerSet === null){
|
||||
return '아국 도시가 아닙니다';
|
||||
}
|
||||
|
||||
if(isOfficerSet($officerSet, $targetOfficerLevel)){
|
||||
return '이미 다른 장수가 임명되어있습니다';
|
||||
}
|
||||
|
||||
//기존 장수 일반으로
|
||||
$db->update('general', [
|
||||
'officer_level'=>1,
|
||||
'officer_city'=>0,
|
||||
], 'officer_level=%i AND officer_city=%i AND no!=%i', $targetOfficerLevel, $cityID, $general->getID());
|
||||
|
||||
if($general instanceof DummyGeneral){
|
||||
return null;
|
||||
}
|
||||
|
||||
if($targetOfficerLevel === 4 && $general->getVar('strength') < GameConst::$chiefStatMin){
|
||||
return '무력이 부족합니다.';
|
||||
}
|
||||
|
||||
if($targetOfficerLevel === 3 && $general->getVar('intel') < GameConst::$chiefStatMin){
|
||||
return '지력이 부족합니다.';
|
||||
}
|
||||
|
||||
//신임 장수
|
||||
$db->update('city', [
|
||||
'officer_set'=>$db->sqleval('officer_set | %i', doOfficerSet(0, $targetOfficerLevel)),
|
||||
], 'city=%i AND nation=%i', $cityID, $nationID);
|
||||
$general->setVar('officer_level', $targetOfficerLevel);
|
||||
$general->setVar('officer_city', $cityID);
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function do추방(General $general, int $myOfficerLevel):?string{
|
||||
$generalID = $general->getID();
|
||||
$generalName = $general->getVar('name');
|
||||
$nationID = $general->getNationID();
|
||||
|
||||
|
||||
|
||||
//추방할사람이 외교권자이면 불가
|
||||
$permission = checkSecretPermission($general->getRaw());
|
||||
if($permission == 4){
|
||||
return '외교권자는 추방할 수 없습니다.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$env = $gameStor->getValues(['startyear','year','month','scenario']);
|
||||
|
||||
$nation = $db->queryFirstRow('SELECT name,chief_set,color FROM nation WHERE nation=%i', $nationID);
|
||||
$nationName = $nation['name'];
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
//이미 지정했다면 무시
|
||||
if(isOfficerSet($nation['chief_set'], $myOfficerLevel) || ($myOfficerLevel == 0 && $myOfficerLevel == 12)) {
|
||||
return '이미 추방 권한을 사용했습니다.';
|
||||
}
|
||||
$gold = 0;
|
||||
$rice = 0;
|
||||
// 금쌀1000이상은 남김
|
||||
if($general->getVar('gold') > GameConst::$defaultGold) {
|
||||
$gold = $general->getVar('gold') - GameConst::$defaultGold;
|
||||
$general->setVar('gold', GameConst::$defaultGold);
|
||||
}
|
||||
if($general->getVar('rice') > GameConst::$defaultRice) {
|
||||
$rice = $general->getVar('rice') - GameConst::$defaultRice;
|
||||
$general->setVar('rice', GameConst::$defaultRice);
|
||||
}
|
||||
|
||||
$general->setVar('nation', 0);
|
||||
$general->setVar('officer_level', 0);
|
||||
$general->setVar('officer_city', 0);
|
||||
$general->setVar('belong', 0);
|
||||
$oldMakeLimit = $general->getVar('makelimit');
|
||||
$general->setVar('makelimit', 12);
|
||||
$general->setVar('permission', 'normal');
|
||||
|
||||
$josaYi = JosaUtil::pick($generalName, '이');
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <D><b>{$nationName}</b></>에서 <R>추방</>당했습니다.");
|
||||
$logger->pushGeneralActionLog("<D><b>{$nationName}</b></>에서 <R>추방</>당했습니다.", ActionLogger::PLAIN);
|
||||
|
||||
// 명성/공헌 N*10%감소
|
||||
if($env['year'] <= $env['startyear'] && $general->getNPCType() < 2){
|
||||
$general->setVar('makelimit', $oldMakeLimit);
|
||||
}
|
||||
else{
|
||||
$betrayCnt = $general->getVar('betray');
|
||||
$general->addExperience(-$general->getVar('experience')*0.1*$betrayCnt);
|
||||
$general->addDedication(-$general->getVar('dedication')*0.1*$betrayCnt);
|
||||
$general->increaseVarWithLimit('betray', 1, null, GameConst::$maxBetrayCnt);
|
||||
}
|
||||
|
||||
//부대장일 경우
|
||||
if($general->getVar('troop') == $generalID){
|
||||
// 모두 탈퇴
|
||||
$db->update('general', [
|
||||
'troop'=>0,
|
||||
], 'troop = %i', $generalID);
|
||||
$db->delete('troop', 'troop_leader=%i', $generalID);
|
||||
}
|
||||
$general->setVar('troop', 0);
|
||||
|
||||
if($general->getNPCType() >= 2 && ($env['scenario'] < 100 || Util::randBool(0.01))) {
|
||||
|
||||
$str = Util::choiceRandom([
|
||||
'날 버리다니... 곧 전장에서 복수해주겠다...',
|
||||
'추방이라... 내가 무얼 잘못했단 말인가...',
|
||||
'어디 추방해가면서 잘되나 보자... 꼭 복수하겠다...',
|
||||
'인덕이 제일이거늘... 추방이 웬말인가... 저주한다!',
|
||||
'날 추방했으니 그 복수로 적국에 정보를 팔아 넘겨야겠군요. 그럼 이만.'
|
||||
]);
|
||||
|
||||
$src = new MessageTarget(
|
||||
$generalID,
|
||||
$generalName,
|
||||
$nationID,
|
||||
$nation['name'],
|
||||
$nation['color'],
|
||||
GetImageURL($general->getVar('imgsvr'), $general->getVar('picture'))
|
||||
);
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PUBLIC,
|
||||
$src,
|
||||
$src,
|
||||
$str,
|
||||
new \DateTime(),
|
||||
new \DateTime('9999-12-31'),
|
||||
[]
|
||||
);
|
||||
$msg->send();
|
||||
}
|
||||
|
||||
if($env['year'] < $env['startyear']+3) {
|
||||
//초반엔 군주 부상 증가(엔장 임관지양)
|
||||
$db->update('general', [
|
||||
'injury'=>$db->sqleval('least(injury + 1, %i)', 80),
|
||||
], 'nation=%i AND officer_level=12', $nationID);
|
||||
|
||||
$db->update('nation', [
|
||||
'gennum'=>$db->sqleval('gennum - %i', $general->getNPCType()!=5?1:0),
|
||||
'gold'=>$db->sqleval('gold + %i', $gold),
|
||||
'rice'=>$db->sqleval('rice + %i', $rice),
|
||||
], 'nation = %i', $nationID);
|
||||
} else {
|
||||
//이번분기는 추방불가(초반 제외)
|
||||
$db->update('nation', [
|
||||
'chief_set'=>$db->sqleval('chief_set | %i', doOfficerSet(0, $myOfficerLevel)),
|
||||
'gennum'=>$db->sqleval('gennum - %i', $general->getNPCType()!=5?1:0),
|
||||
'gold'=>$db->sqleval('gold + %i', $gold),
|
||||
'rice'=>$db->sqleval('rice + %i', $rice),
|
||||
], 'nation = %i', $nationID);
|
||||
}
|
||||
|
||||
$logger->pushGeneralHistoryLog("<D>{$nation['name']}</>에서 추방됨");
|
||||
$general->applyDB($db);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if($action == "임명") {
|
||||
if(2 <= $officerLevel && $officerLevel <= 4){
|
||||
if(!$destCityID){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'도시가 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
$result = do도시임명($general, $destCityID, $officerLevel);
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
if(5 <= $officerLevel && $officerLevel < 12){
|
||||
$result = do수뇌임명($general, $officerLevel);
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 지정입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($action == "추방") {
|
||||
$result = do추방($general, $myOfficerLevel);
|
||||
if($result !== null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 명령입니다.'
|
||||
]);
|
||||
@@ -59,7 +59,7 @@ list(
|
||||
$npcmode
|
||||
) = $gameStor->getValuesAsArray(['year', 'month', 'maxgeneral', 'npcmode']);
|
||||
|
||||
if(!$npcmode){
|
||||
if($npcmode!=1){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'빙의 가능한 서버가 아닙니다'
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$pick = Util::getPost('pick');
|
||||
$leadership = Util::getPost('leadership', 'int', GameConst::$defaultStatMin);
|
||||
$strength = Util::getPost('leadership', 'int', GameConst::$defaultStatMin);
|
||||
$intel = Util::getPost('leadership', 'int', GameConst::$defaultStatMin);
|
||||
$personal = Util::getPost('personal', 'string', null);
|
||||
$use_own_picture = Util::getPost('use_own_picture', 'bool', false);
|
||||
|
||||
|
||||
if(!$pick){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수를 선택하지 않았습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$rootDB = RootDB::db();
|
||||
$oNow = new \DateTimeImmutable();
|
||||
$now = $oNow->format('Y-m-d H:i:s');
|
||||
|
||||
$hasGeneralID = $db->queryFirstField('SELECT no FROM general WHERE owner = %i', $userID);
|
||||
if($hasGeneralID){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'이미 장수를 생성했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$env = $gameStor->getValues(['startyear', 'year', 'month', 'maxgeneral', 'npcmode', 'show_img_level', 'icon_path', 'turnterm', 'turntime']);
|
||||
$env['fiction'] = false;
|
||||
|
||||
$npcmode = $env['npcmode'];
|
||||
$maxgeneral = $env['maxgeneral'];
|
||||
|
||||
if($npcmode!=2){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'선택 가능한 서버가 아닙니다'
|
||||
]);
|
||||
}
|
||||
|
||||
$selectInfo = $db->queryFirstField('SELECT info FROM select_pool WHERE `owner` = %i AND `reserved_until`>=%s AND `unique_name`=%s', $userID, $now, $pick);
|
||||
if(!$selectInfo){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'유효한 장수 목록이 없습니다.'
|
||||
]);
|
||||
}
|
||||
$selectInfo = Json::decode($selectInfo);
|
||||
|
||||
$ownerInfo = RootDB::db()->queryFirstRow('SELECT `name`,`picture`,`imgsvr` FROM member WHERE `NO`=%i',$userID);
|
||||
if(!$ownerInfo){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'멤버 정보를 가져오지 못했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
|
||||
if ($gencount >= $maxgeneral) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'더 이상 등록 할 수 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$poolClass = getGeneralPoolClass(GameConst::$targetGeneralPool);
|
||||
/** @var AbsGeneralPool */
|
||||
$pickedGeneral = new $poolClass($db, $selectInfo, $now);
|
||||
|
||||
$builder = $pickedGeneral->getGeneralBuilder();
|
||||
|
||||
foreach(GameConst::$generalPoolAllowOption as $allowOption){
|
||||
if($allowOption == 'stat'){
|
||||
$leadership = Util::valueFit($leadership, GameConst::$defaultStatMin, GameConst::$defaultStatMax);
|
||||
$strength = Util::valueFit($strength, GameConst::$defaultStatMin, GameConst::$defaultStatMax);
|
||||
$intel = Util::valueFit($intel, GameConst::$defaultStatMin, GameConst::$defaultStatMax);
|
||||
|
||||
if($leadership + $strength + $intel > GameConst::$defaultStatTotal){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'스탯의 총 합이 올바르지 않습니다.'
|
||||
]);
|
||||
}
|
||||
$builder->setStat($leadership, $strength, $intel);
|
||||
}
|
||||
else if($allowOption == 'picture' && $use_own_picture){
|
||||
$builder->setPicture($ownerInfo['imgsvr'], $ownerInfo['picture']);
|
||||
}
|
||||
else if($allowOption == 'ego'){
|
||||
if(!$personal || $personal == 'Random'){
|
||||
$personal = Util::choiceRandom(GameConst::$availablePersonality);
|
||||
}
|
||||
if(!array_search($personal, GameConst::$availablePersonality)){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 성격입니다.'
|
||||
]);
|
||||
}
|
||||
$builder->setEgo($personal);
|
||||
}
|
||||
}
|
||||
|
||||
$userNick = $ownerInfo['name'];
|
||||
|
||||
$builder->setOwner($userID);
|
||||
$builder->setOwnerName($userNick);
|
||||
$builder->setKillturn(5);
|
||||
$builder->setNPCType(0);
|
||||
$builder->setAuxVar('next_change', TimeUtil::nowAddMinutes(12 * $env['turnterm']));
|
||||
$builder->fillRemainSpecAsZero($env);
|
||||
$builder->build($env);
|
||||
$generalID = $builder->getGeneralID();
|
||||
if(!$generalID){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수 등록에 실패했습니다.'
|
||||
]);
|
||||
}
|
||||
$pickedGeneral->occupyGeneralName();
|
||||
|
||||
$db->update('select_pool',[
|
||||
'owner'=>null,
|
||||
'reserved_until'=>null,
|
||||
], '(owner=%i or reserved_until < %s) AND general_id is NULL', $userID, $now);
|
||||
|
||||
|
||||
$josaYi = JosaUtil::pick($userNick, '이');
|
||||
$generalName = $builder->getGeneralName();
|
||||
$josaRo = JosaUtil::pick($generalName, '로');
|
||||
|
||||
$cityName = CityConst::byID($builder->getCityID())->name;
|
||||
|
||||
$logger = new ActionLogger($generalID, 0, $env['year'], $env['month']);
|
||||
$logger->pushGeneralHistoryLog("<Y>{$generalName}</>, <G>{$cityName}</>에서 등장");
|
||||
$logger->pushGlobalActionLog("<G><b>{$cityName}</b></>에서 <Y>{$userNick}</>{$josaYi} <Y>{$generalName}</>{$josaRo} 등장합니다.");
|
||||
$logger->flush();
|
||||
|
||||
pushAdminLog(["가입 : {$userID} // {$session->userName} // {$pick} // ".getenv("REMOTE_ADDR")]);
|
||||
|
||||
$rootDB->insert('member_log', [
|
||||
'member_no' => $userID,
|
||||
'date'=>TimeUtil::now(),
|
||||
'action_type'=>'make_general',
|
||||
'action'=>Json::encode([
|
||||
'server'=>DB::prefix(),
|
||||
'type'=>'select',
|
||||
'generalID'=>$generalID,
|
||||
'generalName'=>$generalName
|
||||
])
|
||||
]);
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
@@ -43,7 +43,7 @@ $session = Session::requireLogin([
|
||||
'game'=>null,
|
||||
'me'=>null
|
||||
])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$userID = $session->userID;
|
||||
|
||||
if(!class_exists('\\sammo\\DB')){
|
||||
Json::die([
|
||||
@@ -91,7 +91,8 @@ if(file_exists(__DIR__.'/.htaccess')){
|
||||
'scenarioName'=>$options['scenarioName'],
|
||||
'turnterm'=>$options['turnterm'],
|
||||
'fictionMode'=>($options['fiction']?'가상':'사실'),
|
||||
'npcMode'=>($options['npcmode']?'가능':'불가'),
|
||||
'block_general_create'=>(!!$options['block_general_create']),
|
||||
'npcMode'=>([0=>'불가',1=>'가능',2=>'선택 생성'][$options['npcmode']]),
|
||||
'openDatetime'=>$reserved['date'],
|
||||
'starttime'=>$options['starttime'],
|
||||
'gameConf'=>$options['gameConf'],
|
||||
@@ -104,7 +105,7 @@ if(file_exists(__DIR__.'/.htaccess')){
|
||||
|
||||
//TODO: 천통시에도 예약 오픈 알림이 필요..?
|
||||
|
||||
$admin = $gameStor->getValues(['isunited', 'npcmode', 'year', 'month', 'scenario', 'scenario_text', 'maxgeneral', 'turnterm', 'opentime', 'turntime', 'join_mode', 'fiction', 'autorun_user']);
|
||||
$admin = $gameStor->getValues(['isunited', 'npcmode', 'year', 'month', 'scenario', 'scenario_text', 'maxgeneral', 'turnterm', 'opentime', 'turntime', 'join_mode', 'fiction', 'block_general_create', 'autorun_user']);
|
||||
$admin['maxUserCnt'] = $admin['maxgeneral'];
|
||||
$admin['npcMode'] = $admin['npcmode'];
|
||||
$admin['turnTerm'] = $admin['turnterm'];
|
||||
@@ -124,8 +125,8 @@ $admin['scenario'] = $admin['scenario_text'];
|
||||
$admin['userCnt'] = $genCnt;
|
||||
$admin['npcCnt'] = $npcCnt;
|
||||
$admin['nationCnt'] = $nationCnt;
|
||||
|
||||
$admin['npcMode'] = $admin['npcMode']?'가능':'불가';
|
||||
$admin['block_general_create'] = !!$admin['block_general_create'];
|
||||
$admin['npcMode'] = [0=>'불가',1=>'가능',2=>'선택 생성'][$admin['npcMode']];
|
||||
$admin['fictionMode'] = $admin['fiction']?'가상':'사실';
|
||||
|
||||
$otherTextInfo = [];
|
||||
|
||||
+75
-76
@@ -1,77 +1,76 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$generalID = $session->generalID;
|
||||
|
||||
increaseRefresh("내정보 수정", 0);
|
||||
|
||||
$action = Util::getPost('action');
|
||||
$tnmt = Util::getPost('tnmt', 'int', 1);
|
||||
$defence_train = Util::getPost('defence_train', 'int', 80);
|
||||
$use_treatment = Util::getPost('use_treatment', 'int', 10);
|
||||
//$detachNPC = Util::getPost('detachNPC', 'bool');
|
||||
$detachNPC = false;
|
||||
|
||||
if ($defence_train <= 40) {
|
||||
$defence_train = 40;
|
||||
}
|
||||
|
||||
if($defence_train <= 90){
|
||||
$defence_train = Util::round($defence_train, -1);
|
||||
}
|
||||
else{
|
||||
$defence_train = 999;
|
||||
}
|
||||
|
||||
if($tnmt < 0 || $tnmt > 1){
|
||||
$tnmt = 1;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$me = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
|
||||
if($defence_train != $me->getVar('defence_train')){
|
||||
if($defence_train == 999){
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
$me->increaseVar('train', -3);
|
||||
$me->increaseVar('atmos', -3);
|
||||
}
|
||||
else{
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
}
|
||||
}
|
||||
|
||||
$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100));
|
||||
|
||||
if($me->getVar('tnmt') != $tnmt){
|
||||
$me->setVar('tnmt', $tnmt);
|
||||
}
|
||||
|
||||
if($me->getNPCType() == 1 && $detachNPC){
|
||||
$turnterm = $gameStor->turnterm;
|
||||
|
||||
if($turnterm < 10){
|
||||
$targetKillTurn = 30 / $turnterm;
|
||||
}
|
||||
else{
|
||||
$targetKillTurn = 60 / $turnterm;
|
||||
}
|
||||
$me->setVar('killturn', $targetKillTurn);
|
||||
}
|
||||
|
||||
$me->applyDB($db);
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
$generalID = $session->generalID;
|
||||
|
||||
increaseRefresh("내정보 수정", 0);
|
||||
|
||||
$action = Util::getPost('action');
|
||||
$tnmt = Util::getPost('tnmt', 'int', 1);
|
||||
$defence_train = Util::getPost('defence_train', 'int', 80);
|
||||
$use_treatment = Util::getPost('use_treatment', 'int', 10);
|
||||
$use_auto_nation_turn = Util::getPost('use_auto_nation_turn', 'int', 1);
|
||||
//$detachNPC = Util::getPost('detachNPC', 'bool');
|
||||
$detachNPC = false;
|
||||
|
||||
if ($defence_train <= 40) {
|
||||
$defence_train = 40;
|
||||
}
|
||||
|
||||
if($defence_train <= 90){
|
||||
$defence_train = Util::round($defence_train, -1);
|
||||
}
|
||||
else{
|
||||
$defence_train = 999;
|
||||
}
|
||||
|
||||
if($tnmt < 0 || $tnmt > 1){
|
||||
$tnmt = 1;
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$me = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
|
||||
if($defence_train !== $me->getVar('defence_train')){
|
||||
if($defence_train == 999){
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
$me->increaseVarWithLimit('train', -3, 20);
|
||||
$me->increaseVarWithLimit('atmos', -3, 20);
|
||||
}
|
||||
else{
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
}
|
||||
}
|
||||
|
||||
$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100));
|
||||
$me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn);
|
||||
$me->setVar('tnmt', $tnmt);
|
||||
|
||||
if($me->getNPCType() == 1 && $detachNPC){
|
||||
$turnterm = $gameStor->turnterm;
|
||||
|
||||
if($turnterm < 10){
|
||||
$targetKillTurn = 30 / $turnterm;
|
||||
}
|
||||
else{
|
||||
$targetKillTurn = 60 / $turnterm;
|
||||
}
|
||||
$me->setVar('killturn', $targetKillTurn);
|
||||
}
|
||||
|
||||
$me->applyDB($db);
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
+69
-57
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
@@ -21,18 +22,18 @@ $availableTypes = [
|
||||
'nationPolicy',
|
||||
];
|
||||
|
||||
if(!in_array($type, $availableTypes)){
|
||||
if (!in_array($type, $availableTypes)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 타입이 아닙니다.',
|
||||
'result' => false,
|
||||
'reason' => '올바른 타입이 아닙니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
$data = Json::decode($data);
|
||||
if(!$data || !is_array($data)){
|
||||
if (!$data || !is_array($data)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 입력이 아닙니다.',
|
||||
'result' => false,
|
||||
'reason' => '올바른 입력이 아닙니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -44,94 +45,95 @@ $me = $db->queryFirstRow('SELECT no, name, npc, nation, city, officer_level, con
|
||||
$nationID = $me['nation'];
|
||||
if (!$nationID) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'국가에 소속되어있지 않습니다.',
|
||||
'result' => false,
|
||||
'reason' => '국가에 소속되어있지 않습니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
$permission = checkSecretPermission($me);
|
||||
if ($permission < 3) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'권한이 부족합니다. 군주, 외교권자, 조언자가 아닙니다.'
|
||||
'result' => false,
|
||||
'reason' => '권한이 부족합니다. 군주, 외교권자, 조언자가 아닙니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
function applyNationPolicy($policy, $nationID, $generalName):?string{
|
||||
function applyNationPolicy($policy, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
$defaultPolicy = AutorunNationPolicy::$defaultPolicy;
|
||||
$troopCache = null;
|
||||
foreach($db->queryFirstColumn('SELECT troop_leader FROM troop WHERE nation=%i',$nationID) as $troopID){
|
||||
foreach ($db->queryFirstColumn('SELECT troop_leader FROM troop WHERE nation=%i', $nationID) as $troopID) {
|
||||
$troopCache[$troopID] = 'Neutral';
|
||||
}
|
||||
$cityList = CityConst::all();
|
||||
$nationPolicyRoot = $nationStor->npc_nation_policy;
|
||||
$nationPolicy = $nationPolicyRoot['values']??[];
|
||||
foreach($policy as $key=>$val){
|
||||
$nationPolicy = $nationPolicyRoot['values'] ?? [];
|
||||
foreach ($policy as $key => $val) {
|
||||
|
||||
if($key === 'CombatForce'){
|
||||
if(!is_array($val)){
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
if ($key === 'CombatForce') {
|
||||
if (!is_array($val)) {
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
}
|
||||
foreach($val as $troopID=>$troopTarget){
|
||||
if(!key_exists($troopID, $troopCache)){
|
||||
foreach ($val as $troopID => $troopTarget) {
|
||||
if (!key_exists($troopID, $troopCache)) {
|
||||
return "{$troopID}는 국가의 부대가 아닙니다.";
|
||||
}
|
||||
if($troopCache[$troopID] != 'Neutral'){
|
||||
if ($troopCache[$troopID] != 'Neutral') {
|
||||
return "부대({$troopID}는 하나의 역할만 지정할 수 있습니다.";
|
||||
}
|
||||
if(!is_array($troopTarget) || count($troopTarget)!=2){
|
||||
if (!is_array($troopTarget) || count($troopTarget) != 2) {
|
||||
return "{$troopID}의 입력양식이 올바르지 않습니다.";
|
||||
}
|
||||
[$fromCity, $toCity] = $troopCache;
|
||||
if(!key_exists($fromCity, $cityList) || !key_exists($toCity, $cityList)){
|
||||
if (!key_exists($fromCity, $cityList) || !key_exists($toCity, $cityList)) {
|
||||
return "{$troopID}의 도시 {$fromCity}, {$toCity}가 올바른 도시 번호가 아닙니다.";
|
||||
}
|
||||
$troopCache[$troopID]=$key;
|
||||
$troopCache[$troopID] = $key;
|
||||
}
|
||||
$nationPolicy[$key]=$val;
|
||||
$nationPolicy[$key] = $val;
|
||||
continue;
|
||||
}
|
||||
if(in_array($key, ['SupportForce', 'DevelopForce'])){
|
||||
if(!is_array($val)){
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
if (in_array($key, ['SupportForce', 'DevelopForce'])) {
|
||||
if (!is_array($val)) {
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
}
|
||||
foreach($val as $troopID){
|
||||
if(!key_exists($troopID, $troopCache)){
|
||||
foreach ($val as $troopID) {
|
||||
if (!key_exists($troopID, $troopCache)) {
|
||||
return "{$troopID}는 국가의 부대가 아닙니다.";
|
||||
}
|
||||
if($troopCache[$troopID] != 'Neutral'){
|
||||
if ($troopCache[$troopID] != 'Neutral') {
|
||||
return "부대({$troopID}는 하나의 역할만 지정할 수 있습니다.";
|
||||
}
|
||||
$troopCache[$troopID]=$key;
|
||||
$troopCache[$troopID] = $key;
|
||||
}
|
||||
|
||||
$nationPolicy[$key]=array_values($val);
|
||||
$nationPolicy[$key] = array_values($val);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(!key_exists($key, $defaultPolicy)){
|
||||
if (!key_exists($key, $defaultPolicy)) {
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
}
|
||||
$defaultValue = $defaultPolicy[$key];
|
||||
if(is_numeric($defaultValue) != is_numeric($val)){
|
||||
if (is_numeric($defaultValue) != is_numeric($val)) {
|
||||
return "{$key}는 올바른 값이 아닙니다.";
|
||||
}
|
||||
if(is_integer($defaultValue) != is_integer($val)){
|
||||
if (is_integer($defaultValue) != is_integer($val)) {
|
||||
return "{$key}는 올바른 값이 아닙니다.";
|
||||
}
|
||||
if(is_array($defaultValue) != is_array($val)){
|
||||
if (is_array($defaultValue) != is_array($val)) {
|
||||
return "{$key}는 올바른 값이 아닙니다.";
|
||||
}
|
||||
if(is_integer($val) && $val < 0){
|
||||
if (is_integer($val) && $val < 0) {
|
||||
$val = 0;
|
||||
}
|
||||
$nationPolicy[$key] = $val;
|
||||
}
|
||||
|
||||
|
||||
$nationPolicyRoot['values'] = $nationPolicy;
|
||||
$nationPolicyRoot['valueSetter'] = $generalName;
|
||||
$nationPolicyRoot['valueSetTime'] = TimeUtil::now();
|
||||
@@ -139,14 +141,15 @@ function applyNationPolicy($policy, $nationID, $generalName):?string{
|
||||
return null;
|
||||
}
|
||||
|
||||
function applyNationPriority($priority, $nationID, $generalName):?string{
|
||||
function applyNationPriority($priority, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationPolicyRoot = $nationStor->npc_nation_policy;
|
||||
|
||||
$defaultPriority = AutorunNationPolicy::$defaultPriority;
|
||||
foreach($priority as $item){
|
||||
if(!in_array($item, $defaultPriority)){
|
||||
foreach ($priority as $item) {
|
||||
if (!in_array($item, $defaultPriority)) {
|
||||
return "{$item}은 올바른 명령이 아닙니다.";
|
||||
}
|
||||
}
|
||||
@@ -157,17 +160,29 @@ function applyNationPriority($priority, $nationID, $generalName):?string{
|
||||
return null;
|
||||
}
|
||||
|
||||
function applyGeneralPriority($priority, $nationID, $generalName):?string{
|
||||
function applyGeneralPriority($priority, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$generalPolicyRoot = $nationStor->npc_general_policy;
|
||||
|
||||
$defaultPriority = AutorunGeneralPolicy::$default_priority;
|
||||
foreach($priority as $item){
|
||||
if(!in_array($item, $defaultPriority)){
|
||||
$mustHaveActions = ['출병' => 1];
|
||||
foreach ($priority as $item) {
|
||||
if (key_exists($item, $mustHaveActions)) {
|
||||
$mustHaveActions[$item] = 0;
|
||||
}
|
||||
if (!in_array($item, $defaultPriority)) {
|
||||
return "{$item}은 올바른 명령이 아닙니다.";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($mustHaveActions as $actionKey => $unset) {
|
||||
if ($unset) {
|
||||
return "{$actionKey}은 항상 사용해야 합니다.";
|
||||
}
|
||||
}
|
||||
|
||||
$generalPolicyRoot['priority'] = $priority;
|
||||
$generalPolicyRoot['prioritySetter'] = $generalName;
|
||||
$generalPolicyRoot['prioritySetTime'] = TimeUtil::now();
|
||||
@@ -175,26 +190,23 @@ function applyGeneralPriority($priority, $nationID, $generalName):?string{
|
||||
return null;
|
||||
}
|
||||
|
||||
if($type == 'nationPolicy'){
|
||||
if ($type == 'nationPolicy') {
|
||||
$result = applyNationPolicy($data, $nationID, $me['name']);
|
||||
}
|
||||
else if($type == 'generalPriority'){
|
||||
} else if ($type == 'generalPriority') {
|
||||
$result = applyGeneralPriority($data, $nationID, $me['name']);
|
||||
}
|
||||
else if($type == 'nationPriority'){
|
||||
} else if ($type == 'nationPriority') {
|
||||
$result = applyNationPriority($data, $nationID, $me['name']);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
if($result!==null){
|
||||
if ($result !== null) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result,
|
||||
'result' => false,
|
||||
'reason' => $result,
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
]);
|
||||
'result' => true,
|
||||
'reason' => 'success',
|
||||
]);
|
||||
|
||||
+467
-451
@@ -1,451 +1,467 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
increaseRefresh("시뮬레이터", 0);
|
||||
|
||||
$query = Util::getPost('query');
|
||||
if($query === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'입력값이 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$action = Util::getPost('action');
|
||||
if($action === null || !in_array($action, ['reorder', 'battle'])){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'원하는 동작이 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$query = Json::decode($query);
|
||||
if($query === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 JSON입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$defaultCheck = [
|
||||
'required'=>[
|
||||
'attackerGeneral', 'attackerCity', 'attackerNation',
|
||||
'defenderGenerals', 'defenderCity', 'defenderNation',
|
||||
'year', 'month', 'repeatCnt'
|
||||
],
|
||||
'integer'=>[
|
||||
'year','month','repeatCnt'
|
||||
],
|
||||
'between'=>[
|
||||
['month', [1, 12]]
|
||||
],
|
||||
'in'=>[
|
||||
['repeatCnt', [1, 1000]]
|
||||
],
|
||||
'min'=>[
|
||||
['year', 0]
|
||||
],
|
||||
'array'=>[
|
||||
'attackerGeneral', 'attackerCity', 'attackerNation',
|
||||
'defenderGenerals', 'defenderCity', 'defenderNation'
|
||||
],
|
||||
];
|
||||
|
||||
$v = new Validator($query);
|
||||
$v->rules($defaultCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$year = $query['year'];
|
||||
$month = $query['month'];
|
||||
$repeatCnt = $query['repeatCnt'];
|
||||
|
||||
$rawAttacker = $query['attackerGeneral'];
|
||||
$rawAttacker['turntime'] = TimeUtil::now();
|
||||
$rawAttackerCity = $query['attackerCity'];
|
||||
$rawAttackerNation = $query['attackerNation'];
|
||||
|
||||
$rawDefenderList = $query['defenderGenerals'];
|
||||
$rawDefenderCity = $query['defenderCity'];
|
||||
$rawDefenderNation = $query['defenderNation'];
|
||||
|
||||
|
||||
$generalCheck = [
|
||||
'required'=>[
|
||||
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
|
||||
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
|
||||
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
||||
'recent_war'
|
||||
],
|
||||
'integer'=>[
|
||||
'no', 'nation', 'crew', 'crewtype', 'atmos', 'train',
|
||||
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
|
||||
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
||||
],
|
||||
'min'=>[
|
||||
['no', 1],
|
||||
['nation', 1],
|
||||
['crew', 0],
|
||||
['intel', 0],
|
||||
['strength', 0],
|
||||
['leadership', 0],
|
||||
['experience', 0],
|
||||
['gold', 0],
|
||||
['rice', 0],
|
||||
['dex1', 0],
|
||||
['dex2', 0],
|
||||
['dex3', 0],
|
||||
['dex4', 0],
|
||||
['dex5', 0],
|
||||
],
|
||||
'between'=>[
|
||||
['train', [40, GameConst::$maxTrainByWar]],
|
||||
['atmos', [40, GameConst::$maxAtmosByWar]],
|
||||
['explevel', [0, 300]],
|
||||
['injury', [0, 80]],
|
||||
['officer_level', [1, 12]]
|
||||
],
|
||||
'in'=>[
|
||||
['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)],
|
||||
['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)],
|
||||
['crewtype', array_keys(GameUnitConst::all())],
|
||||
['horse', array_merge(array_keys(GameConst::$allItems['horse']), ['None'])],
|
||||
['weapon', array_merge(array_keys(GameConst::$allItems['weapon']), ['None'])],
|
||||
['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])],
|
||||
['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])],
|
||||
]
|
||||
];
|
||||
|
||||
$v = new Validator($rawAttacker);
|
||||
$v->rules($generalCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병자]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$defenderList = [];
|
||||
foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
|
||||
$v = new Validator($rawDefenderGeneral);
|
||||
$v->rules($generalCheck);
|
||||
if(!$v->validate()){
|
||||
$idx+=1;
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>"[수비자{$idx}]".$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$defenderList[] = new General($rawDefenderGeneral, null, $rawDefenderCity, $rawAttackerNation, $year, $month, true);
|
||||
}
|
||||
|
||||
|
||||
$cityCheck = [
|
||||
'required'=>[
|
||||
'city', 'nation', 'supply', 'name',
|
||||
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
|
||||
'trust', 'level',
|
||||
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
||||
'dead', 'state', 'conflict',
|
||||
],
|
||||
'numeric'=>[
|
||||
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
|
||||
],
|
||||
'integer'=>[
|
||||
'city', 'nation', 'supply',
|
||||
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
||||
'state',
|
||||
],
|
||||
'min'=>[
|
||||
['def', 0],
|
||||
['wall', 0],
|
||||
['trust', 0],
|
||||
['pop', 0],
|
||||
['comm', 0],
|
||||
['secu', 0],
|
||||
['city', 1],
|
||||
['nation', 0]
|
||||
],
|
||||
'in'=>[
|
||||
['level', array_keys(getCityLevelList())]
|
||||
]
|
||||
];
|
||||
|
||||
$v = new Validator($rawAttackerCity);
|
||||
$v->rules($cityCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병도시]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$v = new Validator($rawDefenderCity);
|
||||
$v->rules($cityCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[수비도시]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$nationCheck = [
|
||||
'required'=>[
|
||||
'type', 'tech', 'level', 'capital',
|
||||
'nation', 'name', 'gold', 'rice', 'gennum'
|
||||
],
|
||||
'integer'=>[
|
||||
'level', 'capital', 'nation', 'gennum',
|
||||
],
|
||||
'numeric'=>[
|
||||
'tech', 'gold', 'rice'
|
||||
],
|
||||
'min'=>[
|
||||
['tech', 0],
|
||||
['gold', 0],
|
||||
['rice', 0],
|
||||
['gennum', 1],
|
||||
],
|
||||
'in'=>[
|
||||
['type', GameConst::$availableNationType],
|
||||
['level', array_keys(getNationLevelList())]
|
||||
]
|
||||
];
|
||||
|
||||
$v = new Validator($rawAttackerNation);
|
||||
$v->rules($nationCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병국]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$v = new Validator($rawDefenderNation);
|
||||
$v->rules($nationCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[수비국]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
if($action == 'reorder'){
|
||||
usort($defenderList, function(General $lhs, General $rhs){
|
||||
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
|
||||
});
|
||||
|
||||
$order = [];
|
||||
foreach($defenderList as $defenderGeneral){
|
||||
$order[] = $defenderGeneral->getID();
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'order'=>$order
|
||||
]);
|
||||
}
|
||||
|
||||
usort($defenderList, function(General $lhs, General $rhs){
|
||||
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
|
||||
});
|
||||
|
||||
$rawDefenderList = array_map(function(General $general){
|
||||
return $general->getRaw();
|
||||
}, $defenderList);
|
||||
unset($defenderList);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$startYear = $gameStor->startyear;
|
||||
$cityRate = Util::round(($year - $startYear) / 1.5) + 60;
|
||||
|
||||
|
||||
function simulateBattle(
|
||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
||||
$startYear, $year, $month, $cityRate
|
||||
){
|
||||
$attacker = new WarUnitGeneral(
|
||||
new General($rawAttacker, null, $rawAttackerCity, $rawAttackerNation, $year, $month),
|
||||
$rawAttackerNation,
|
||||
true
|
||||
);
|
||||
$city = new WarUnitCity($rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate);
|
||||
|
||||
$iterDefender = new \ArrayIterator($rawDefenderList);
|
||||
$iterDefender->rewind();
|
||||
|
||||
$battleResult = [];
|
||||
|
||||
$attackerRice = $rawAttacker['rice'];
|
||||
$defenderRice = 0;
|
||||
|
||||
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
|
||||
use ($iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice) {
|
||||
if($prevDefender !== null){
|
||||
$prevDefender->getLogger()->rollback();
|
||||
$battleResult[] = $prevDefender;
|
||||
if($prevDefender instanceof WarUnitGeneral){
|
||||
$defenderRice -= $prevDefender->getVar('rice');
|
||||
}
|
||||
}
|
||||
|
||||
if(!$reqNext){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!$iterDefender->valid()){
|
||||
return null;
|
||||
}
|
||||
|
||||
$defenderObj = new General($iterDefender->current(), null, $rawDefenderCity, $rawDefenderNation, $year, $month);
|
||||
if(extractBattleOrder($defenderObj) <= 0){
|
||||
return null;
|
||||
}
|
||||
|
||||
$defenderRice += $defenderObj->getVar('rice');
|
||||
|
||||
$retVal = new WarUnitGeneral(
|
||||
$defenderObj,
|
||||
$rawDefenderNation,
|
||||
false
|
||||
);
|
||||
$iterDefender->next();
|
||||
return $retVal;
|
||||
};
|
||||
|
||||
$conquerCity = processWar_NG($attacker, $getNextDefender, $city, $year - $startYear);
|
||||
|
||||
$rawDefenderCity = $city->getRaw();
|
||||
$updateAttackerNation = [];
|
||||
$updateDefenderNation = [];
|
||||
|
||||
$attackerRice -= $attacker->getVar('rice');
|
||||
|
||||
if($city->getPhase() > 0){
|
||||
$rice = $city->getKilled() / 100 * 0.8;
|
||||
$rice *= $city->getCrewType()->rice;
|
||||
$rice *= getTechCost($rawDefenderNation['tech']);
|
||||
$rice *= $cityRate / 100 - 0.2;
|
||||
Util::setRound($rice);
|
||||
|
||||
$defenderRice += $rice;
|
||||
}
|
||||
|
||||
$totalDead = $attacker->getKilled() + $attacker->getDead();
|
||||
$attackerCityDead = $totalDead * 0.4;
|
||||
$defenderCityDead = $totalDead * 0.6;
|
||||
|
||||
return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice];
|
||||
}
|
||||
|
||||
$lastWarLog = [];
|
||||
|
||||
$attackerKilled = 0;
|
||||
$attackerDead = 0;
|
||||
|
||||
$attackerMaxKilled = 0;
|
||||
$attackerMinKilled = PHP_INT_MAX;
|
||||
|
||||
$attackerMaxDead = 0;
|
||||
$attackerMinDead = PHP_INT_MAX;
|
||||
|
||||
|
||||
$attackerAvgRice = 0;
|
||||
$defenderAvgRice = 0;
|
||||
|
||||
$avgPhase = 0;
|
||||
$avgWar = 0;
|
||||
|
||||
$attackerActivatedSkills = [];
|
||||
$defendersActivatedSkills = [];
|
||||
|
||||
foreach(Util::range($repeatCnt) as $repeatIdx){
|
||||
/** @var WarUnit $attacker */
|
||||
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
|
||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
||||
$startYear, $year, $month, $cityRate
|
||||
);
|
||||
$lastWarLog = Util::mapWithKey(function($key, $values){
|
||||
return ConvertLog(join('<br>', $values));
|
||||
}, $attacker->getLogger()->rollback());
|
||||
|
||||
$avgPhase += $attacker->getPhase() / $repeatCnt;
|
||||
|
||||
$killed = $attacker->getKilled();
|
||||
$dead = $attacker->getDead();
|
||||
|
||||
$attackerKilled += $killed / $repeatCnt;
|
||||
$attackerDead += $dead / $repeatCnt;
|
||||
|
||||
$attackerMaxKilled = max($attackerMaxKilled, $killed);
|
||||
$attackerMinKilled = min($attackerMinKilled, $killed);
|
||||
|
||||
$attackerMaxDead = max($attackerMaxDead, $dead);
|
||||
$attackerMinDead = min($attackerMinDead, $dead);
|
||||
|
||||
$attackerAvgRice += $attackerRice / $repeatCnt;
|
||||
$defenderAvgRice += $defenderRice / $repeatCnt;
|
||||
|
||||
$avgWar += count($battleResult) / $repeatCnt;
|
||||
|
||||
foreach($attacker->getActivatedSkillLog() as $skillName => $skillCnt){
|
||||
if(!key_exists($skillName, $attackerActivatedSkills)){
|
||||
$attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
||||
}
|
||||
else{
|
||||
$attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($battleResult as $idx=>$defender){
|
||||
while($idx >= count($defendersActivatedSkills)){
|
||||
$defendersActivatedSkills[] = [];
|
||||
}
|
||||
|
||||
$activatedSkills = &$defendersActivatedSkills[$idx];
|
||||
foreach($defender->getActivatedSkillLog() as $skillName => $skillCnt){
|
||||
if(!key_exists($skillName, $activatedSkills)){
|
||||
$activatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
||||
}
|
||||
else{
|
||||
$activatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'datetime'=>$rawAttacker['turntime'],
|
||||
'reason'=>'success',
|
||||
'lastWarLog'=>$lastWarLog,
|
||||
'avgWar'=>$avgWar,
|
||||
'phase'=>$avgPhase,
|
||||
'killed'=>$attackerKilled,
|
||||
'maxKilled'=>$attackerMaxKilled,
|
||||
'minKilled'=>$attackerMinKilled,
|
||||
'dead'=>$attackerDead,
|
||||
'maxDead'=>$attackerMaxDead,
|
||||
'minDead'=>$attackerMinDead,
|
||||
'attackerRice'=>$attackerAvgRice,
|
||||
'defenderRice'=>$defenderAvgRice,
|
||||
'attackerSkills'=>$attackerActivatedSkills,
|
||||
'defendersSkills'=>$defendersActivatedSkills,
|
||||
]);
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireLogin([])->setReadOnly();
|
||||
$userID = Session::getUserID();
|
||||
|
||||
increaseRefresh("시뮬레이터", 0);
|
||||
|
||||
$query = Util::getPost('query');
|
||||
if($query === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'입력값이 없습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$action = Util::getPost('action');
|
||||
if($action === null || !in_array($action, ['reorder', 'battle'])){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'원하는 동작이 지정되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$query = Json::decode($query);
|
||||
if($query === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 JSON입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$defaultCheck = [
|
||||
'required'=>[
|
||||
'attackerGeneral', 'attackerCity', 'attackerNation',
|
||||
'defenderGenerals', 'defenderCity', 'defenderNation',
|
||||
'year', 'month', 'repeatCnt'
|
||||
],
|
||||
'integer'=>[
|
||||
'year','month','repeatCnt'
|
||||
],
|
||||
'between'=>[
|
||||
['month', [1, 12]]
|
||||
],
|
||||
'in'=>[
|
||||
['repeatCnt', [1, 1000]]
|
||||
],
|
||||
'min'=>[
|
||||
['year', 0]
|
||||
],
|
||||
'array'=>[
|
||||
'attackerGeneral', 'attackerCity', 'attackerNation',
|
||||
'defenderGenerals', 'defenderCity', 'defenderNation'
|
||||
],
|
||||
];
|
||||
|
||||
$v = new Validator($query);
|
||||
$v->rules($defaultCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$year = $query['year'];
|
||||
$month = $query['month'];
|
||||
$repeatCnt = $query['repeatCnt'];
|
||||
|
||||
$rawAttacker = $query['attackerGeneral'];
|
||||
$rawAttacker['turntime'] = TimeUtil::now();
|
||||
$rawAttackerCity = $query['attackerCity'];
|
||||
$rawAttackerNation = $query['attackerNation'];
|
||||
|
||||
$rawDefenderList = $query['defenderGenerals'];
|
||||
$rawDefenderCity = $query['defenderCity'];
|
||||
$rawDefenderNation = $query['defenderNation'];
|
||||
|
||||
|
||||
$generalCheck = [
|
||||
'required'=>[
|
||||
'no', 'name', 'nation', 'turntime', 'personal', 'special2', 'crew', 'crewtype', 'atmos', 'train',
|
||||
'intel', 'intel_exp', 'book', 'strength', 'strength_exp', 'weapon', 'injury', 'leadership', 'leadership_exp', 'horse', 'item',
|
||||
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
||||
'recent_war', 'warnum', 'killnum', 'killcrew',
|
||||
],
|
||||
'integer'=>[
|
||||
'no', 'nation', 'crew', 'crewtype', 'atmos', 'train',
|
||||
'intel', 'intel_exp', 'strength', 'strength_exp', 'injury', 'leadership', 'leadership_exp',
|
||||
'explevel', 'experience', 'dedication', 'officer_level', 'officer_city', 'gold', 'rice', 'dex1', 'dex2', 'dex3', 'dex4', 'dex5',
|
||||
'warnum', 'killnum', 'killcrew',
|
||||
],
|
||||
'min'=>[
|
||||
['no', 1],
|
||||
['nation', 1],
|
||||
['crew', 0],
|
||||
['intel', 0],
|
||||
['strength', 0],
|
||||
['leadership', 0],
|
||||
['experience', 0],
|
||||
['gold', 0],
|
||||
['rice', 0],
|
||||
['dex1', 0],
|
||||
['dex2', 0],
|
||||
['dex3', 0],
|
||||
['dex4', 0],
|
||||
['dex5', 0],
|
||||
['warnum', 0],
|
||||
['killnum', 0],
|
||||
['killcrew', 0],
|
||||
],
|
||||
'between'=>[
|
||||
['train', [40, GameConst::$maxTrainByWar]],
|
||||
['atmos', [40, GameConst::$maxAtmosByWar]],
|
||||
['explevel', [0, 300]],
|
||||
['injury', [0, 80]],
|
||||
['officer_level', [1, 12]]
|
||||
],
|
||||
'in'=>[
|
||||
['personal', array_merge(GameConst::$availablePersonality, GameConst::$optionalPersonality)],
|
||||
['special2', array_merge(GameConst::$availableSpecialWar, GameConst::$optionalSpecialWar)],
|
||||
['crewtype', array_keys(GameUnitConst::all())],
|
||||
['horse', array_merge(array_keys(GameConst::$allItems['horse']), ['None'])],
|
||||
['weapon', array_merge(array_keys(GameConst::$allItems['weapon']), ['None'])],
|
||||
['book', array_merge(array_keys(GameConst::$allItems['book']), ['None'])],
|
||||
['item', array_merge(array_keys(GameConst::$allItems['item']), ['None'])],
|
||||
]
|
||||
];
|
||||
|
||||
$v = new Validator($rawAttacker);
|
||||
$v->rules($generalCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병자]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$rawAttacker['owner'] = 0;
|
||||
|
||||
$defenderList = [];
|
||||
foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
|
||||
$v = new Validator($rawDefenderGeneral);
|
||||
$v->rules($generalCheck);
|
||||
if(!$v->validate()){
|
||||
$idx+=1;
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>"[수비자{$idx}]".$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$rawDefenderGeneral['owner'] = 0;
|
||||
|
||||
$defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
|
||||
}
|
||||
|
||||
|
||||
$cityCheck = [
|
||||
'required'=>[
|
||||
'city', 'nation', 'supply', 'name',
|
||||
'pop', 'agri', 'comm', 'secu', 'def', 'wall',
|
||||
'trust', 'level',
|
||||
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
||||
'dead', 'state', 'conflict',
|
||||
],
|
||||
'numeric'=>[
|
||||
'pop', 'agri', 'comm', 'secu', 'def', 'wall', 'trust', 'dead'
|
||||
],
|
||||
'integer'=>[
|
||||
'city', 'nation', 'supply',
|
||||
'pop_max', 'agri_max', 'comm_max', 'secu_max', 'def_max', 'wall_max',
|
||||
'state',
|
||||
],
|
||||
'min'=>[
|
||||
['def', 0],
|
||||
['wall', 0],
|
||||
['trust', 0],
|
||||
['pop', 0],
|
||||
['comm', 0],
|
||||
['secu', 0],
|
||||
['city', 1],
|
||||
['nation', 0]
|
||||
],
|
||||
'in'=>[
|
||||
['level', array_keys(getCityLevelList())]
|
||||
]
|
||||
];
|
||||
|
||||
$v = new Validator($rawAttackerCity);
|
||||
$v->rules($cityCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병도시]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$v = new Validator($rawDefenderCity);
|
||||
$v->rules($cityCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[수비도시]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$nationCheck = [
|
||||
'required'=>[
|
||||
'type', 'tech', 'level', 'capital',
|
||||
'nation', 'name', 'gold', 'rice', 'gennum'
|
||||
],
|
||||
'integer'=>[
|
||||
'level', 'capital', 'nation', 'gennum',
|
||||
],
|
||||
'numeric'=>[
|
||||
'tech', 'gold', 'rice'
|
||||
],
|
||||
'min'=>[
|
||||
['tech', 0],
|
||||
['gold', 0],
|
||||
['rice', 0],
|
||||
['gennum', 1],
|
||||
],
|
||||
'in'=>[
|
||||
['type', GameConst::$availableNationType],
|
||||
['level', array_keys(getNationLevelList())]
|
||||
]
|
||||
];
|
||||
|
||||
$v = new Validator($rawAttackerNation);
|
||||
$v->rules($nationCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병국]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
$v = new Validator($rawDefenderNation);
|
||||
$v->rules($nationCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[수비국]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
|
||||
if($action == 'reorder'){
|
||||
usort($defenderList, function(General $lhs, General $rhs){
|
||||
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
|
||||
});
|
||||
|
||||
$order = [];
|
||||
foreach($defenderList as $defenderGeneral){
|
||||
$order[] = $defenderGeneral->getID();
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
'order'=>$order
|
||||
]);
|
||||
}
|
||||
|
||||
usort($defenderList, function(General $lhs, General $rhs){
|
||||
return -(extractBattleOrder($lhs) <=> extractBattleOrder($rhs));
|
||||
});
|
||||
|
||||
$rawDefenderList = array_map(function(General $general){
|
||||
return $general->getRaw();
|
||||
}, $defenderList);
|
||||
unset($defenderList);
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$startYear = $gameStor->startyear;
|
||||
$cityRate = Util::round(($year - $startYear) / 1.5) + 60;
|
||||
|
||||
function extractRankVar(array $rawVal):array{
|
||||
$rankVars = [];
|
||||
foreach($rawVal as $rawKey=>$rawVal){
|
||||
if(key_exists($rawKey, General::RANK_COLUMN)){
|
||||
$rankVars[$rawKey] = $rawVal;
|
||||
}
|
||||
}
|
||||
return $rankVars;
|
||||
}
|
||||
|
||||
function simulateBattle(
|
||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
||||
$startYear, $year, $month, $cityRate
|
||||
){
|
||||
$attacker = new WarUnitGeneral(
|
||||
new General($rawAttacker, extractRankVar($rawAttacker), $rawAttackerCity, $rawAttackerNation, $year, $month),
|
||||
$rawAttackerNation,
|
||||
true
|
||||
);
|
||||
$city = new WarUnitCity($rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate);
|
||||
|
||||
$iterDefender = new \ArrayIterator($rawDefenderList);
|
||||
$iterDefender->rewind();
|
||||
|
||||
$battleResult = [];
|
||||
|
||||
$attackerRice = $rawAttacker['rice'];
|
||||
$defenderRice = 0;
|
||||
|
||||
$getNextDefender = function(?WarUnit $prevDefender, bool $reqNext)
|
||||
use ($iterDefender, $rawDefenderCity, $rawDefenderNation, $year, $month, &$battleResult, &$defenderRice) {
|
||||
if($prevDefender !== null){
|
||||
$prevDefender->getLogger()->rollback();
|
||||
$battleResult[] = $prevDefender;
|
||||
if($prevDefender instanceof WarUnitGeneral){
|
||||
$defenderRice -= $prevDefender->getVar('rice');
|
||||
}
|
||||
}
|
||||
|
||||
if(!$reqNext){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(!$iterDefender->valid()){
|
||||
return null;
|
||||
}
|
||||
|
||||
$defenderObj = new General($iterDefender->current(), extractRankVar($iterDefender->current()), $rawDefenderCity, $rawDefenderNation, $year, $month);
|
||||
if(extractBattleOrder($defenderObj) <= 0){
|
||||
return null;
|
||||
}
|
||||
|
||||
$defenderRice += $defenderObj->getVar('rice');
|
||||
|
||||
$retVal = new WarUnitGeneral(
|
||||
$defenderObj,
|
||||
$rawDefenderNation,
|
||||
false
|
||||
);
|
||||
$iterDefender->next();
|
||||
return $retVal;
|
||||
};
|
||||
|
||||
$conquerCity = processWar_NG($attacker, $getNextDefender, $city, $year - $startYear);
|
||||
|
||||
$rawDefenderCity = $city->getRaw();
|
||||
$updateAttackerNation = [];
|
||||
$updateDefenderNation = [];
|
||||
|
||||
$attackerRice -= $attacker->getVar('rice');
|
||||
|
||||
if($city->getPhase() > 0){
|
||||
$rice = $city->getKilled() / 100 * 0.8;
|
||||
$rice *= $city->getCrewType()->rice;
|
||||
$rice *= getTechCost($rawDefenderNation['tech']);
|
||||
$rice *= $cityRate / 100 - 0.2;
|
||||
Util::setRound($rice);
|
||||
|
||||
$defenderRice += $rice;
|
||||
}
|
||||
|
||||
$totalDead = $attacker->getKilled() + $attacker->getDead();
|
||||
$attackerCityDead = $totalDead * 0.4;
|
||||
$defenderCityDead = $totalDead * 0.6;
|
||||
|
||||
return [$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice];
|
||||
}
|
||||
|
||||
$lastWarLog = [];
|
||||
|
||||
$attackerKilled = 0;
|
||||
$attackerDead = 0;
|
||||
|
||||
$attackerMaxKilled = 0;
|
||||
$attackerMinKilled = PHP_INT_MAX;
|
||||
|
||||
$attackerMaxDead = 0;
|
||||
$attackerMinDead = PHP_INT_MAX;
|
||||
|
||||
|
||||
$attackerAvgRice = 0;
|
||||
$defenderAvgRice = 0;
|
||||
|
||||
$avgPhase = 0;
|
||||
$avgWar = 0;
|
||||
|
||||
$attackerActivatedSkills = [];
|
||||
$defendersActivatedSkills = [];
|
||||
|
||||
foreach(Util::range($repeatCnt) as $repeatIdx){
|
||||
/** @var WarUnit $attacker */
|
||||
[$attacker, $city, $battleResult, $conquerCity, $attackerRice, $defenderRice] = simulateBattle(
|
||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
||||
$startYear, $year, $month, $cityRate
|
||||
);
|
||||
$lastWarLog = Util::mapWithKey(function($key, $values){
|
||||
return ConvertLog(join('<br>', $values));
|
||||
}, $attacker->getLogger()->rollback());
|
||||
|
||||
$avgPhase += $attacker->getPhase() / $repeatCnt;
|
||||
|
||||
$killed = $attacker->getKilled();
|
||||
$dead = $attacker->getDead();
|
||||
|
||||
$attackerKilled += $killed / $repeatCnt;
|
||||
$attackerDead += $dead / $repeatCnt;
|
||||
|
||||
$attackerMaxKilled = max($attackerMaxKilled, $killed);
|
||||
$attackerMinKilled = min($attackerMinKilled, $killed);
|
||||
|
||||
$attackerMaxDead = max($attackerMaxDead, $dead);
|
||||
$attackerMinDead = min($attackerMinDead, $dead);
|
||||
|
||||
$attackerAvgRice += $attackerRice / $repeatCnt;
|
||||
$defenderAvgRice += $defenderRice / $repeatCnt;
|
||||
|
||||
$avgWar += count($battleResult) / $repeatCnt;
|
||||
|
||||
foreach($attacker->getActivatedSkillLog() as $skillName => $skillCnt){
|
||||
if(!key_exists($skillName, $attackerActivatedSkills)){
|
||||
$attackerActivatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
||||
}
|
||||
else{
|
||||
$attackerActivatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
||||
}
|
||||
}
|
||||
|
||||
foreach($battleResult as $idx=>$defender){
|
||||
while($idx >= count($defendersActivatedSkills)){
|
||||
$defendersActivatedSkills[] = [];
|
||||
}
|
||||
|
||||
$activatedSkills = &$defendersActivatedSkills[$idx];
|
||||
foreach($defender->getActivatedSkillLog() as $skillName => $skillCnt){
|
||||
if(!key_exists($skillName, $activatedSkills)){
|
||||
$activatedSkills[$skillName] = $skillCnt / $repeatCnt;
|
||||
}
|
||||
else{
|
||||
$activatedSkills[$skillName] += $skillCnt / $repeatCnt;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'datetime'=>$rawAttacker['turntime'],
|
||||
'reason'=>'success',
|
||||
'lastWarLog'=>$lastWarLog,
|
||||
'avgWar'=>$avgWar,
|
||||
'phase'=>$avgPhase,
|
||||
'killed'=>$attackerKilled,
|
||||
'maxKilled'=>$attackerMaxKilled,
|
||||
'minKilled'=>$attackerMinKilled,
|
||||
'dead'=>$attackerDead,
|
||||
'maxDead'=>$attackerMaxDead,
|
||||
'minDead'=>$attackerMinDead,
|
||||
'attackerRice'=>$attackerAvgRice,
|
||||
'defenderRice'=>$defenderAvgRice,
|
||||
'attackerSkills'=>$attackerActivatedSkills,
|
||||
'defendersSkills'=>$defendersActivatedSkills,
|
||||
]);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user