forked from devsam/core
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7a3642296a
|
||
|
|
87e57aea0e
|
||
|
|
ea256790ec
|
||
|
|
4cbd824ee0
|
||
|
|
4db1a4b32e
|
||
|
|
c060e05553
|
||
|
|
92cd195276
|
||
|
|
f9b270fef3
|
||
|
|
3f12dfd8ba
|
||
|
|
d7e57f30eb
|
||
|
|
ff822561cd
|
||
|
|
273973f4b6
|
||
|
|
c648e2df85
|
||
|
|
9b7e0ef169
|
||
|
|
6eccd248ea
|
||
|
|
eaaa1c5da8
|
||
|
|
95776cda5c
|
||
|
|
8ae0323dcc
|
||
|
|
f2d0020d92
|
||
|
|
67f3004eb0
|
||
|
|
f933c0616b | ||
|
|
a240c6f901
|
||
|
|
e2c2ae0360
|
||
|
|
bcd0117cdd
|
||
|
|
83f233cc99
|
||
|
|
4f21eab7b1
|
||
|
|
864ddf7efe
|
||
|
|
9d3636cc49
|
||
|
|
ce4f656030
|
||
|
|
a94f080cde
|
||
|
|
71ca873c7a
|
||
|
|
6e0d13e1fb
|
||
|
|
059c4d999a
|
||
|
|
f52e357e8a
|
||
|
|
761496be5c
|
||
|
|
551972d876
|
||
|
|
81c2fc4d43
|
||
|
|
3e542fcbfa
|
||
|
|
c9ab2c593d
|
||
|
|
0c9e00e90a
|
||
|
|
ea17972478
|
||
|
|
3d40df9755
|
||
|
|
b4ac348645
|
||
|
|
374611f66c
|
||
|
|
39b66fd626
|
||
|
|
75dca322b4 | ||
|
|
cfdae1ddfa
|
||
|
|
054a6c7073
|
||
|
|
e93d9e6cf5
|
||
|
|
30d99c6fc3
|
||
|
|
56c9b44c93
|
||
|
|
919ae5a863
|
||
|
|
43b8e546f6
|
||
|
|
b90aef662b
|
||
|
|
1da47863ae
|
||
|
|
81bd5c1914
|
||
|
|
b14f9a638f
|
||
|
|
8ff3a5a7a8
|
||
|
|
48c77bd6a2
|
||
|
|
35a017c1dc | ||
|
|
a3e8a10da9
|
||
|
|
142b96836e
|
||
|
|
9be0d2ec2d
|
||
|
|
fd817650e7
|
||
|
|
3c6cb96a9b
|
||
|
|
c4537454f9
|
||
|
|
82cdaa433e
|
||
|
|
32dd3ff43f
|
||
|
|
6a5840faaa
|
||
|
|
5b0a3b064d
|
||
|
|
14b8bb9790
|
||
|
|
650f4a5903 | ||
|
|
c50410a6da | ||
|
|
b2a676cd8b | ||
|
|
50a75e4543 | ||
|
|
22172ac66f | ||
|
|
392aaa343d | ||
|
|
d924f47d58 | ||
|
|
3b70cbe724 | ||
|
|
5c3233f883 | ||
|
|
b570bfa9d4 | ||
|
|
270cb25285 | ||
|
|
7d3b0db924 | ||
|
|
74d310e113 | ||
|
|
45afb1c090 | ||
|
|
40fc2f8bbf
|
||
|
|
a9de5a92e1
|
||
|
|
c592b00c3f
|
||
|
|
2c81be4d12
|
||
|
|
f10289f7b6
|
||
|
|
c1f06b4ce5 | ||
|
|
9ad3dbba90
|
||
|
|
12c62f87f7
|
||
|
|
635f1ae077
|
||
|
|
c89bd2f63f
|
||
|
|
2f94a8a2ca | ||
|
|
85b0d35af0 | ||
|
|
b25acacb1e | ||
|
|
c05a43f3b1
|
||
|
|
d99976daa9
|
||
|
|
62f53d09bf
|
||
|
|
88c78ec892
|
||
|
|
006ca76922
|
||
|
|
8cb2e2a447
|
||
|
|
517c85d003
|
||
|
|
83556b710c
|
||
|
|
a43b9091f8
|
||
|
|
e83a1bef49
|
||
|
|
1147a8262c
|
||
|
|
8a987cc55e
|
||
|
|
b28ca864f9
|
||
|
|
4bf77a5c55
|
||
|
|
4ebc20f182
|
||
|
|
9eff1ccaed
|
||
|
|
66170c98dd
|
||
|
|
397c054c66
|
||
|
|
0611551dc0
|
||
|
|
008f88d995
|
||
|
|
7fe450bc07
|
||
|
|
a88ec71b44
|
||
|
|
8a5a3b67f7
|
||
|
|
63771da876
|
||
|
|
68891fafdb
|
||
|
|
df31300a0b
|
||
|
|
16fb782bbf
|
||
|
|
ed3e013a53
|
||
|
|
0bf568a655
|
||
|
|
a5e481af96
|
||
|
|
78a9641c14
|
||
|
|
b517000650
|
||
|
|
1d20eb3c3e
|
||
|
|
8248ccbcd5
|
||
|
|
b880b9bace
|
||
|
|
2da374410b
|
||
|
|
fff8f9493b
|
||
|
|
987baaa307
|
||
|
|
9512ea9b52
|
||
|
|
b0f3c1c97d
|
||
|
|
e823b97cf2
|
||
|
|
203859ee5f
|
||
|
|
4870e2fa30
|
||
|
|
970b702a2b
|
||
|
|
053288b227
|
||
|
|
e9b975bea7
|
||
|
|
89fda44db8
|
||
|
|
fac8536095
|
||
|
|
c79e65b6b7
|
||
|
|
677e65ff6d
|
||
|
|
0c7589d524
|
||
|
|
da27ae2bad
|
||
|
|
f8cd58bcb3 | ||
|
|
3671a289b8 | ||
|
|
48f4dbec50 | ||
|
|
bdb29006e9 | ||
|
|
5ea324f103 | ||
|
|
2f0cd32c18 | ||
|
|
e8911d40df | ||
|
|
89f173e7e3 | ||
|
|
b0ab3f6ace | ||
|
|
641af435d4 | ||
|
|
16a2f20af0 | ||
|
|
79734a6dcf | ||
|
|
2e2ff1b150 | ||
|
|
5ce899ee6e | ||
|
|
e041080773 | ||
|
|
f8448fbb51 | ||
|
|
8defcd29a4 | ||
|
|
fba60df9d1 | ||
|
|
a4ff1f44ba |
@@ -10,8 +10,10 @@
|
||||
*.log
|
||||
|
||||
logs/*.txt
|
||||
api_log.db
|
||||
d_log/*.txt
|
||||
d_log/*.zip
|
||||
d_log/*.db
|
||||
sess_*
|
||||
*/logs/*.txt
|
||||
*/logs/*/*.txt
|
||||
|
||||
@@ -98,12 +98,6 @@ return [
|
||||
'hwe/j_load_scenarios.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',
|
||||
'hwe/j_msg_get_old.php',
|
||||
'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',
|
||||
@@ -112,7 +106,6 @@ return [
|
||||
'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',
|
||||
|
||||
+3
-3
@@ -17,7 +17,6 @@
|
||||
"league/plates": "^3.3",
|
||||
"vlucas/valitron": "^1.4",
|
||||
"php-extended/php-tail": "^2.1",
|
||||
"pguardiario/phpuri": "^1.0",
|
||||
"symfony/lock": "^6.0",
|
||||
"ezyang/htmlpurifier": "^4.10",
|
||||
"xemlock/htmlpurifier-html5": "^0.1.7",
|
||||
@@ -26,8 +25,9 @@
|
||||
"nette/caching": "^3.0",
|
||||
"illuminate/database": "^9.12",
|
||||
"illuminate/events": "^9.12",
|
||||
"spatie/data-transfer-object": "^3.7",
|
||||
"php-ds/php-ds": "^1.4"
|
||||
"php-ds/php-ds": "^1.4",
|
||||
"hided62/ldto": "^1.0",
|
||||
"league/uri": "^6.8"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
Generated
+280
-93
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "908099160e2765c04448fef3f35794c4",
|
||||
"content-hash": "d7acaa437c3c6f48c9a643c9dc4ef421",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brandonwamboldt/utilphp",
|
||||
@@ -537,6 +537,60 @@
|
||||
},
|
||||
"time": "2021-06-11T22:34:44+00:00"
|
||||
},
|
||||
{
|
||||
"name": "hided62/ldto",
|
||||
"version": "v1.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/hided62/ldto.git",
|
||||
"reference": "4c05401406f8afc1636a90763c13884f8fff0d14"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/hided62/ldto/zipball/4c05401406f8afc1636a90763c13884f8fff0d14",
|
||||
"reference": "4c05401406f8afc1636a90763c13884f8fff0d14",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"phan/phan": "^5.3",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"LDTO\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Hide_D",
|
||||
"email": "hided62@gmail.com",
|
||||
"homepage": "https://hided.net",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "php lightweight dto library",
|
||||
"homepage": "https://github.com/hided62/ldto",
|
||||
"keywords": [
|
||||
"data-transfer-object",
|
||||
"dto",
|
||||
"hided62",
|
||||
"lightweight",
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/hided62/ldto/issues",
|
||||
"source": "https://github.com/hided62/ldto/tree/v1.0.0"
|
||||
},
|
||||
"time": "2022-08-05T14:30:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/bus",
|
||||
"version": "v9.12.2",
|
||||
@@ -1140,6 +1194,177 @@
|
||||
},
|
||||
"time": "2020-12-25T05:00:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/uri",
|
||||
"version": "6.8.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/uri.git",
|
||||
"reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/uri/zipball/a700b4656e4c54371b799ac61e300ab25a2d1d39",
|
||||
"reference": "a700b4656e4c54371b799ac61e300ab25a2d1d39",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"league/uri-interfaces": "^2.3",
|
||||
"php": "^8.1",
|
||||
"psr/http-message": "^1.0.1"
|
||||
},
|
||||
"conflict": {
|
||||
"league/uri-schemes": "^1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^v3.9.5",
|
||||
"nyholm/psr7": "^1.5.1",
|
||||
"php-http/psr7-integration-tests": "^1.1.1",
|
||||
"phpbench/phpbench": "^1.2.6",
|
||||
"phpstan/phpstan": "^1.8.5",
|
||||
"phpstan/phpstan-deprecation-rules": "^1.0",
|
||||
"phpstan/phpstan-phpunit": "^1.1.1",
|
||||
"phpstan/phpstan-strict-rules": "^1.4.3",
|
||||
"phpunit/phpunit": "^9.5.24",
|
||||
"psr/http-factory": "^1.0.1"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-fileinfo": "Needed to create Data URI from a filepath",
|
||||
"ext-intl": "Needed to improve host validation",
|
||||
"league/uri-components": "Needed to easily manipulate URI objects",
|
||||
"psr/http-factory": "Needed to use the URI factory"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "6.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Uri\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ignace Nyamagana Butera",
|
||||
"email": "nyamsprod@gmail.com",
|
||||
"homepage": "https://nyamsprod.com"
|
||||
}
|
||||
],
|
||||
"description": "URI manipulation library",
|
||||
"homepage": "https://uri.thephpleague.com",
|
||||
"keywords": [
|
||||
"data-uri",
|
||||
"file-uri",
|
||||
"ftp",
|
||||
"hostname",
|
||||
"http",
|
||||
"https",
|
||||
"middleware",
|
||||
"parse_str",
|
||||
"parse_url",
|
||||
"psr-7",
|
||||
"query-string",
|
||||
"querystring",
|
||||
"rfc3986",
|
||||
"rfc3987",
|
||||
"rfc6570",
|
||||
"uri",
|
||||
"uri-template",
|
||||
"url",
|
||||
"ws"
|
||||
],
|
||||
"support": {
|
||||
"docs": "https://uri.thephpleague.com",
|
||||
"forum": "https://thephpleague.slack.com",
|
||||
"issues": "https://github.com/thephpleague/uri/issues",
|
||||
"source": "https://github.com/thephpleague/uri/tree/6.8.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/nyamsprod",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2022-09-13T19:58:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/uri-interfaces",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/uri-interfaces.git",
|
||||
"reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/00e7e2943f76d8cb50c7dfdc2f6dee356e15e383",
|
||||
"reference": "00e7e2943f76d8cb50c7dfdc2f6dee356e15e383",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.19",
|
||||
"phpstan/phpstan": "^0.12.90",
|
||||
"phpstan/phpstan-phpunit": "^0.12.19",
|
||||
"phpstan/phpstan-strict-rules": "^0.12.9",
|
||||
"phpunit/phpunit": "^8.5.15 || ^9.5"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "to use the IDNA feature",
|
||||
"symfony/intl": "to use the IDNA feature via Symfony Polyfill"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\Uri\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Ignace Nyamagana Butera",
|
||||
"email": "nyamsprod@gmail.com",
|
||||
"homepage": "https://nyamsprod.com"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for URI representation",
|
||||
"homepage": "http://github.com/thephpleague/uri-interfaces",
|
||||
"keywords": [
|
||||
"rfc3986",
|
||||
"rfc3987",
|
||||
"uri",
|
||||
"url"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/thephpleague/uri-interfaces/issues",
|
||||
"source": "https://github.com/thephpleague/uri-interfaces/tree/2.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/sponsors/nyamsprod",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-06-28T04:27:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "microsoft/tolerant-php-parser",
|
||||
"version": "v0.1.1",
|
||||
@@ -1556,34 +1781,6 @@
|
||||
},
|
||||
"time": "2022-01-24T11:29:14+00:00"
|
||||
},
|
||||
{
|
||||
"name": "pguardiario/phpuri",
|
||||
"version": "1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/monkeysuffrage/phpuri.git",
|
||||
"reference": "ad0a5ec033fe616cfef55578b9c7f2458be8fbfc"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/monkeysuffrage/phpuri/zipball/ad0a5ec033fe616cfef55578b9c7f2458be8fbfc",
|
||||
"reference": "ad0a5ec033fe616cfef55578b9c7f2458be8fbfc",
|
||||
"shasum": ""
|
||||
},
|
||||
"type": "project",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"phpuri.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"description": "A php library for converting relative urls to absolute.",
|
||||
"support": {
|
||||
"issues": "https://github.com/monkeysuffrage/phpuri/issues",
|
||||
"source": "https://github.com/monkeysuffrage/phpuri/tree/1.0.0"
|
||||
},
|
||||
"time": "2015-05-24T09:13:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phan/phan",
|
||||
"version": "5.3.2",
|
||||
@@ -2023,6 +2220,59 @@
|
||||
},
|
||||
"time": "2021-11-05T16:47:00+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/http-message",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/http-message.git",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\Http\\Message\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interface for HTTP messages",
|
||||
"homepage": "https://github.com/php-fig/http-message",
|
||||
"keywords": [
|
||||
"http",
|
||||
"http-message",
|
||||
"psr",
|
||||
"psr-7",
|
||||
"request",
|
||||
"response"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/http-message/tree/master"
|
||||
},
|
||||
"time": "2016-08-06T14:39:51+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/log",
|
||||
"version": "3.0.0",
|
||||
@@ -2238,69 +2488,6 @@
|
||||
},
|
||||
"time": "2021-06-29T04:31:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "spatie/data-transfer-object",
|
||||
"version": "3.7.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/spatie/data-transfer-object.git",
|
||||
"reference": "341f72c77e0fce40ea2e0dcb212cb54dc27bbe72"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/spatie/data-transfer-object/zipball/341f72c77e0fce40ea2e0dcb212cb54dc27bbe72",
|
||||
"reference": "341f72c77e0fce40ea2e0dcb212cb54dc27bbe72",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"illuminate/collections": "^8.36",
|
||||
"jetbrains/phpstorm-attributes": "^1.0",
|
||||
"larapack/dd": "^1.1",
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Spatie\\DataTransferObject\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brent Roose",
|
||||
"email": "brent@spatie.be",
|
||||
"homepage": "https://spatie.be",
|
||||
"role": "Developer"
|
||||
}
|
||||
],
|
||||
"description": "Data transfer objects with batteries included",
|
||||
"homepage": "https://github.com/spatie/data-transfer-object",
|
||||
"keywords": [
|
||||
"data-transfer-object",
|
||||
"spatie"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/spatie/data-transfer-object/issues",
|
||||
"source": "https://github.com/spatie/data-transfer-object/tree/3.7.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://spatie.be/open-source/support-us",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/spatie",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2021-12-30T20:31:10+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v6.0.8",
|
||||
@@ -5337,5 +5524,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "8.1"
|
||||
},
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -90,19 +90,19 @@ if (
|
||||
|
||||
//기본 파일 생성
|
||||
if (!file_exists(AppConf::getUserIconPathFS())) {
|
||||
mkdir(AppConf::getUserIconPathFS());
|
||||
mkdir(AppConf::getUserIconPathFS(), 0775);
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_log')) {
|
||||
mkdir(ROOT . '/d_log');
|
||||
mkdir(ROOT . '/d_log', 0775);
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_setting')) {
|
||||
mkdir(ROOT . '/d_setting');
|
||||
mkdir(ROOT . '/d_setting', 0775);
|
||||
}
|
||||
|
||||
if (!file_exists(ROOT . '/d_shared')) {
|
||||
mkdir(ROOT . '/d_shared');
|
||||
mkdir(ROOT . '/d_shared', 0775);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
CREATE TABLE IF NOT EXISTS "api_log" (
|
||||
"id" INTEGER NOT NULL,
|
||||
"user_id" INTEGER NOT NULL,
|
||||
"ip" TEXT NOT NULL,
|
||||
"date" TEXT NOT NULL,
|
||||
"path" TEXT NOT NULL,
|
||||
"arg" TEXT,
|
||||
"aux" TEXT,
|
||||
PRIMARY KEY("id" AUTOINCREMENT)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "by_date" ON "api_log" (
|
||||
"date" DESC
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS "by_user" ON "api_log" (
|
||||
"user_id" ASC,
|
||||
"date" DESC
|
||||
);
|
||||
@@ -40,8 +40,6 @@ $admin = getAdmin();
|
||||
<tr>
|
||||
<td width=110 align=right>시작시간변경</td>
|
||||
<td width=285><input type=text size=20 maxlength=20 style=color:white;background-color:black;text-align:right; name=starttime value='<?=substr($admin['starttime'], 0, 19)?>'><input type=submit name=btn value=변경1></td>
|
||||
<td width=110 align=right>현재도시훈사</td>
|
||||
<td width=285><?=$admin['city_rate']?></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width=110 align=right>최대 장수</td>
|
||||
|
||||
+10
-8
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
@@ -111,7 +113,7 @@ switch ($btn) {
|
||||
case "경험치1000":
|
||||
$text = $btn . " 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -122,7 +124,7 @@ switch ($btn) {
|
||||
case "공헌치1000":
|
||||
$text = $btn . " 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -133,7 +135,7 @@ switch ($btn) {
|
||||
case "보숙10000":
|
||||
$text = "보병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -143,7 +145,7 @@ switch ($btn) {
|
||||
case "궁숙10000":
|
||||
$text = "궁병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -154,7 +156,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
$text = "기병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -165,7 +167,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
$text = "귀병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -176,7 +178,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
$text = "차병숙련도+10000 지급!";
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
$db->update('general', [
|
||||
@@ -196,7 +198,7 @@ switch ($btn) {
|
||||
case "메세지 전달":
|
||||
$text = $msg ?? '';
|
||||
foreach ($genlist as $generalID) {
|
||||
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
|
||||
$msg->send(true);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
//로그인 검사
|
||||
@@ -18,7 +20,7 @@ $msg = Util::getPost('msg', 'string', '메시지');
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
//NOTE: 왜 기능이 admin2와 admin4가 같이 있는가?
|
||||
//NOTE: 왜 기능이 admin2와 admin4가 같이 있는가?
|
||||
//NOTE: 왜 블럭 시 admin4에선 금쌀을 없애지 않는가?
|
||||
switch ($btn) {
|
||||
case "블럭 해제":
|
||||
@@ -66,7 +68,7 @@ switch ($btn) {
|
||||
$src = MessageTarget::buildQuick($session->generalID);
|
||||
foreach($genlist as $generalID){
|
||||
$msgObj = new Message(
|
||||
Message::MSGTYPE_PRIVATE,
|
||||
MessageType::private,
|
||||
$src,
|
||||
MessageTarget::buildQuick($generalID),
|
||||
$msg,
|
||||
|
||||
@@ -27,7 +27,6 @@ foreach ($db->queryFirstColumn(
|
||||
|
||||
$inheritPointManager = InheritancePointManager::getInstance();
|
||||
foreach(General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj){
|
||||
$inheritPointManager->mergeTotalInheritancePoint($genObj, true);
|
||||
$inheritPointManager->mergeTotalInheritancePoint($genObj);
|
||||
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
|
||||
$inheritPointManager->clearInheritancePoint($genObj);
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ include "func.php";
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
increaseRefresh("갱신정보", 2);
|
||||
increaseRefresh("갱신정보", 1);
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxrefresh', 'maxonline']);
|
||||
|
||||
|
||||
+2
-2
@@ -29,7 +29,7 @@ if ($myset > 0) {
|
||||
$submit = 'hidden';
|
||||
}
|
||||
|
||||
$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2);
|
||||
$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
|
||||
if ($gameStor->turntime <= $gameStor->opentime) {
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
if ($me->getNPCType() == 0 && $me->getNationID() == 0) {
|
||||
@@ -116,7 +116,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
|
||||
<?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>
|
||||
<option value=999 <?= $me->getVar('defence_train') == 999 ? "selected" : ""; ?>><?= formatDefenceTrain(999) ?>[훈련 -3, 사기 -6]</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:14px; value=설정저장><br>
|
||||
|
||||
@@ -65,8 +65,8 @@ if ($nationID) {
|
||||
전역 설정
|
||||
</div>
|
||||
<div class="card-body dragpad_battle">
|
||||
<div class="row">
|
||||
<div class="col-sm-6">
|
||||
<div class="row gx-0">
|
||||
<div class="col-sm-4">
|
||||
<div class="input-group">
|
||||
<input type="number" class="form-control" aria-describedby="text_year" value="<?= $startYear ?>" disabled>
|
||||
<div class="input-group-text"> 년 시작 </div>
|
||||
@@ -76,9 +76,13 @@ if ($nationID) {
|
||||
<div class="input-group-text"> 월 </div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6">
|
||||
<div class="col-sm-5 px-2">
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="input-group me-2" role="group">
|
||||
<div class="input-group-text">
|
||||
시드
|
||||
</div>
|
||||
<input type="text" class="form-control" id="seed" aria-describedby="text_seed">
|
||||
<div class="input-group-text">
|
||||
반복 횟수
|
||||
</div>
|
||||
@@ -87,6 +91,10 @@ if ($nationID) {
|
||||
<option value="1000">1000회 (요약 표기)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-3">
|
||||
<div class="btn-toolbar" role="toolbar">
|
||||
<div class="btn-group me-2" role="group">
|
||||
<button type="button" class="btn btn-danger btn-begin_battle">전투</button>
|
||||
</div>
|
||||
@@ -426,6 +434,25 @@ if ($nationID) {
|
||||
</div>
|
||||
<input type="number" class="form-control form_killcrew" value="0" step="1">
|
||||
</div>
|
||||
|
||||
<div class="input-group mb-0">
|
||||
<div class="input-group-text">자신</div>
|
||||
<div class="input-group-text">회피 확률</div>
|
||||
<input type="number" class="form-control form_war_avoid_ratio" value="0" step="1" min="0" max="5">
|
||||
<div class="input-group-text">필살 확률</div>
|
||||
<input type="number" class="form-control form_war_critical_ratio" value="0" step="1" min="0" max="5">
|
||||
<div class="input-group-text">계략 시도 확률</div>
|
||||
<input type="number" class="form-control form_war_magic_trial_prob" value="0" step="1" min="0" max="5">
|
||||
</div>
|
||||
<div class="input-group mb-1">
|
||||
<div class="input-group-text">상대</div>
|
||||
<div class="input-group-text">회피 확률</div>
|
||||
<input type="number" class="form-control form_oppose_war_avoid_ratio" value="0" step="1" min="0" max="5">
|
||||
<div class="input-group-text">필살 확률</div>
|
||||
<input type="number" class="form-control form_oppose_war_critical_ratio" value="0" step="1" min="0" max="5">
|
||||
<div class="input-group-text">계략 시도 확률</div>
|
||||
<input type="number" class="form-control form_oppose_war_magic_trial_prob" value="0" step="1" min="0" max="5">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
+40
-61
@@ -886,7 +886,7 @@ function generalInfo2(General $generalObj)
|
||||
|
||||
function getOnlineNum(): int
|
||||
{
|
||||
return KVStorage::getStorage(DB::db(), 'game_env')->getValue('online') ?? 0;
|
||||
return KVStorage::getStorage(DB::db(), 'game_env')->getValue('online_user_cnt') ?? 0;
|
||||
}
|
||||
|
||||
function onlinegen(General $general)
|
||||
@@ -906,7 +906,7 @@ function nationMsg(General $general)
|
||||
$nationID = $general->getNationID();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
return $nationStor->notice ?? '';
|
||||
return $nationStor->nationNotice['msg'] ?? '';
|
||||
}
|
||||
|
||||
function banner()
|
||||
@@ -1003,19 +1003,31 @@ function increaseRefresh($type = "", $cnt = 1)
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
|
||||
$isunited = $gameStor->isunited;
|
||||
$opentime = $gameStor->opentime;
|
||||
|
||||
if ($isunited != 2 && $generalID && $userGrade < 6 && $opentime <= TimeUtil::now()) {
|
||||
$db->update('general', [
|
||||
'lastrefresh' => $date,
|
||||
'con' => $db->sqleval('con + %i', $cnt),
|
||||
'connect' => $db->sqleval('connect + %i', $cnt),
|
||||
'refcnt' => $db->sqleval('refcnt + %i', $cnt),
|
||||
'refresh' => $db->sqleval('refresh + %i', $cnt)
|
||||
], 'owner=%i', $userID);
|
||||
if($userGrade == 6){
|
||||
return;
|
||||
}
|
||||
if($isunited == 2){
|
||||
return;
|
||||
}
|
||||
if(!$generalID){
|
||||
return;
|
||||
}
|
||||
if($opentime > $date){
|
||||
return;
|
||||
}
|
||||
|
||||
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
|
||||
|
||||
$db->update('general', [
|
||||
'lastrefresh' => $date,
|
||||
'con' => $db->sqleval('con + %i', $cnt),
|
||||
'connect' => $db->sqleval('connect + %i', $cnt),
|
||||
'refcnt' => $db->sqleval('refcnt + %i', $cnt),
|
||||
'refresh' => $db->sqleval('refresh + %i', $cnt)
|
||||
], 'owner=%i', $userID);
|
||||
|
||||
$date = date('Y_m_d H:i:s');
|
||||
$date2 = substr($date, 0, 10);
|
||||
@@ -1033,42 +1045,6 @@ function increaseRefresh($type = "", $cnt = 1)
|
||||
),
|
||||
FILE_APPEND
|
||||
);
|
||||
|
||||
$proxy_headers = array(
|
||||
'HTTP_VIA',
|
||||
'HTTP_X_FORWARDED_FOR',
|
||||
'HTTP_FORWARDED_FOR',
|
||||
'HTTP_X_FORWARDED',
|
||||
'HTTP_FORWARDED',
|
||||
'HTTP_CLIENT_IP',
|
||||
'HTTP_FORWARDED_FOR_IP',
|
||||
'VIA',
|
||||
'X_FORWARDED_FOR',
|
||||
'FORWARDED_FOR',
|
||||
'X_FORWARDED',
|
||||
'FORWARDED',
|
||||
'CLIENT_IP',
|
||||
'FORWARDED_FOR_IP',
|
||||
'HTTP_PROXY_CONNECTION'
|
||||
);
|
||||
|
||||
$str = "";
|
||||
foreach ($proxy_headers as $x) {
|
||||
if (isset($_SERVER[$x])) $str .= "//{$x}:{$_SERVER[$x]}";
|
||||
}
|
||||
if ($str != "") {
|
||||
file_put_contents(
|
||||
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_ipcheck.txt",
|
||||
sprintf(
|
||||
"%s, %s, %s%s\n",
|
||||
$session->userName,
|
||||
$session->generalName,
|
||||
$_SERVER['REMOTE_ADDR'],
|
||||
$str
|
||||
),
|
||||
FILE_APPEND
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function updateTraffic()
|
||||
@@ -1223,10 +1199,9 @@ function updateOnline()
|
||||
$nationname[$nation['nation']] = $nation['name'];
|
||||
}
|
||||
|
||||
|
||||
//동접수
|
||||
$before5Min = TimeUtil::nowAddMinutes(-5);
|
||||
$onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh > %s AND npc < 2', $before5Min);
|
||||
$startTurn = cutTurn($gameStor->turntime, $gameStor->turnterm, false);
|
||||
$onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh >= %s AND npc < 2', $startTurn);
|
||||
$onlineNum = count($onlineUser);
|
||||
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
|
||||
|
||||
@@ -1745,7 +1720,8 @@ function tryUniqueItemLottery(RandUtil $rng, General $general, string $acquireTy
|
||||
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
|
||||
}
|
||||
|
||||
$prob = Util::valueFit($prob, null, 1 / 4); //최대치 감소
|
||||
$prob *= GameConst::$uniqueTrialCoef;
|
||||
$prob = Util::valueFit($prob, null, GameConst::$maxUniqueTrialProb); //최대치 감소
|
||||
$result = false;
|
||||
|
||||
$prob /= sqrt(7);
|
||||
@@ -1805,16 +1781,16 @@ function deleteNation(General $lord, bool $applyDB): array
|
||||
$nationID,
|
||||
$lordID
|
||||
),
|
||||
['npc', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
|
||||
['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
|
||||
1
|
||||
);
|
||||
$nationGeneralList[$lordID] = $lord;
|
||||
|
||||
$nation['generals'] = array_keys($nationGeneralList);
|
||||
$nation['aux'] = Json::decode($nation['aux']);
|
||||
$nation['msg'] = $nationStor->notice;
|
||||
$nation['msg'] = $nationStor->nationNotice['msg'] ?? '';
|
||||
$nation['scout_msg'] = $nationStor->scout_msg;
|
||||
$nation['aux'] += $nationStor->max_power;
|
||||
$nation['aux'] += $nationStor->max_power ?? [];
|
||||
$nation['history'] = getNationHistoryLogAll($nationID);
|
||||
|
||||
$josaYi = JosaUtil::pick($nationName, '이');
|
||||
@@ -1823,13 +1799,16 @@ function deleteNation(General $lord, bool $applyDB): array
|
||||
|
||||
// 전 장수 재야로
|
||||
foreach ($nationGeneralList as $general) {
|
||||
$general->setAuxVar(
|
||||
InheritanceKey::max_belong->value,
|
||||
max(
|
||||
$general->getVar('belong'),
|
||||
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
|
||||
)
|
||||
);
|
||||
if($general->getNPCType() < 2){
|
||||
$general->setAuxVar(
|
||||
InheritanceKey::max_belong->value,
|
||||
max(
|
||||
$general->getVar('belong'),
|
||||
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$general->setVar('belong', 0);
|
||||
$general->setVar('troop', 0);
|
||||
$general->setVar('officer_level', 0);
|
||||
|
||||
+59
-44
@@ -285,13 +285,8 @@ function preUpdateMonthly()
|
||||
'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;
|
||||
|
||||
//매달 사망자 수입 결산
|
||||
@@ -528,7 +523,7 @@ function checkWander(RandUtil $rng)
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
|
||||
$admin = $gameStor->getValues(['year', 'month']);
|
||||
$admin = $gameStor->getValues(['year', 'month', 'init_year', 'init_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');
|
||||
|
||||
@@ -559,32 +554,39 @@ function updateNationState()
|
||||
$startYear = $admin['startyear'];
|
||||
|
||||
$assemblerCnts = [];
|
||||
|
||||
$nationCityCounts = [];
|
||||
foreach($db->queryAllLists('SELECT nation, count(*) FROM city WHERE LEVEL>=4 GROUP BY nation') as [$nationID, $cityCnt]){
|
||||
$nationCityCounts[$nationID] = $cityCnt;
|
||||
}
|
||||
|
||||
foreach ($db->queryAllLists('SELECT nation,count(no) FROM general WHERE npc = 5 GROUP BY nation') as [$nationID, $assemblerCnt]) {
|
||||
$assemblerCnts[$nationID] = $assemblerCnt;
|
||||
};
|
||||
|
||||
$nationLevelByCityCnt = [
|
||||
0, //방랑군
|
||||
1, //호족
|
||||
2, //군벌
|
||||
5, //주자사
|
||||
8, //주목
|
||||
11, //공
|
||||
16, //왕
|
||||
21, //황제
|
||||
];
|
||||
|
||||
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
|
||||
//TODO: level이 진관수이소중대특 체계를 벗어날 수 있음
|
||||
$nationID = $nation['nation'];
|
||||
$citycount = $db->queryFirstField('SELECT count(*) FROM city WHERE nation=%i AND level>=4', $nationID);
|
||||
$cityCnt = $nationCityCounts[$nationID] ?? 0;
|
||||
|
||||
|
||||
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; // 황제
|
||||
/** @var int */
|
||||
$nationlevel = 0;
|
||||
foreach($nationLevelByCityCnt as $cmpNationLevel => $cmpCityCnt){
|
||||
if($cityCnt < $cmpCityCnt){
|
||||
break;
|
||||
}
|
||||
$nationlevel = $cmpNationLevel;
|
||||
}
|
||||
|
||||
if ($nationlevel > $nation['level']) {
|
||||
@@ -598,33 +600,47 @@ function updateNationState()
|
||||
'rice' => $db->sqleval('rice + %i', $nationlevel * 1000),
|
||||
];
|
||||
|
||||
$nationName = $nation['name'];
|
||||
$lordName = $db->queryFirstField('SELECT name FROM general WHERE nation = %i AND officer_level = 12', $nationID);
|
||||
|
||||
$oldNationLevelText = getNationLevel($oldLevel);
|
||||
$nationLevelText = getNationLevel($nationlevel);
|
||||
|
||||
$logger = new ActionLogger(0, $nationID, $year, $month, false);
|
||||
$josaYi = JosaUtil::pick($lordName, '이');
|
||||
|
||||
switch ($nationlevel) {
|
||||
case 7:
|
||||
$josaUl = JosaUtil::pick(getNationLevel($nationlevel), '을');
|
||||
$history[] = "<C>●</>{$year}년 {$month}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭하였습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$year}년 {$month}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭"]);
|
||||
case 7: //황제
|
||||
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
||||
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><D><b>{$nationName}</b></> {$oldNationLevelText} <Y>{$lordName}</>{$josaYi} <C>{$nationLevelText}</>{$josaRo} 옹립되었습니다.");
|
||||
$logger->pushNationalHistoryLog("<D><b>{$nationName}</b></> {$oldNationLevelText} <Y>{$lordName}</>{$josaYi} <C>{$nationLevelText}</>{$josaRo} 옹립");
|
||||
$auxVal = Json::decode($nation['aux']);
|
||||
$auxVal['can_국기변경'] = 1;
|
||||
$auxVal['can_국호변경'] = 1;
|
||||
$updateVals['aux'] = Json::encode($auxVal);
|
||||
break;
|
||||
case 6:
|
||||
$history[] = "<C>●</>{$year}년 {$month}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극하였습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$year}년 {$month}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극"]);
|
||||
case 6: //왕
|
||||
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
||||
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 책봉되었습니다.");
|
||||
$logger->pushNationalHistoryLog("<D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 책봉");
|
||||
break;
|
||||
case 5:
|
||||
case 4:
|
||||
case 3:
|
||||
$history[] = "<C>●</>{$year}년 {$month}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명되었습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$year}년 {$month}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명됨"]);
|
||||
case 5: //공
|
||||
case 4: //주목
|
||||
case 3: //주자사
|
||||
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
||||
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 임명되었습니다.");
|
||||
$logger->pushNationalHistoryLog("<D><b>{$nationName}</b></>의 <Y>{$lordName}</>{$josaYi} <C>$nationLevelText</>{$josaRo} 임명됨");
|
||||
break;
|
||||
case 2:
|
||||
$history[] = "<C>●</>{$year}년 {$month}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 독립하여 <Y>" . getNationLevel($nationlevel) . "</>로 나섰습니다.";
|
||||
pushNationHistoryLog($nation['nation'], ["<C>●</>{$year}년 {$month}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>로 나서다"]);
|
||||
case 2: //군벌
|
||||
$josaRa = JosaUtil::pick($nationName, '라');
|
||||
$josaRo = JosaUtil::pick($nationLevelText, '로');
|
||||
$logger->pushGlobalHistoryLog("<Y><b>【작위】</b></><Y>{$lordName}</>{$josaYi} 독립하여 <D><b>{$nationName}</b></>{$josaRa}는 <C>$nationLevelText</>{$josaRo} 나섰습니다.");
|
||||
$logger->pushNationalHistoryLog("<Y>{$lordName}</>{$josaYi} 독립하여 <D><b>{$nationName}</b></>{$josaRa}는 <C>$nationLevelText</>{$josaRo} 나서다");
|
||||
break;
|
||||
}
|
||||
|
||||
$db->update('nation', $updateVals, 'nation=%i', $nation['nation']);
|
||||
$logger->flush();
|
||||
|
||||
$turnRows = [];
|
||||
foreach (Util::range(getNationChiefLevel($nation['level']), 12) as $chiefLevel) {
|
||||
@@ -1076,9 +1092,8 @@ function checkEmperior()
|
||||
}
|
||||
processSumInheritPointRank();
|
||||
foreach ($allUserGenerals as $genObj) {
|
||||
$inheritPointManager->mergeTotalInheritancePoint($genObj, true);
|
||||
$inheritPointManager->mergeTotalInheritancePoint($genObj);
|
||||
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
|
||||
$inheritPointManager->clearInheritancePoint($genObj);
|
||||
}
|
||||
|
||||
$gameStor->isunited = 2;
|
||||
@@ -1147,9 +1162,9 @@ function checkEmperior()
|
||||
$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['msg'] = $nationStor->nationNotice['msg'] ?? '';;
|
||||
$nation['scout_msg'] = $nationStor->scout_msg;
|
||||
$nation['aux'] += $nationStor->max_power;
|
||||
$nation['aux'] += $nationStor->max_power ?? [];
|
||||
$nation['history'] = getNationHistoryLogAll($nation['nation']);
|
||||
|
||||
storeOldGenerals(0, $admin['year'], $admin['month']);
|
||||
@@ -1226,7 +1241,7 @@ function checkEmperior()
|
||||
]);
|
||||
|
||||
$hiddenSeed = UniqueConst::$hiddenSeed;
|
||||
$history = ["<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【통일】</b></><D><b>{$nation['name']}</b></>{$josaYi} 전토를 통일하였습니다. <span class='hidden_but_copyable'>(서버시드: $hiddenSeed})</span>"];
|
||||
$history = ["<C>●</>{$admin['year']}년 {$admin['month']}월:<Y><b>【통일】</b></><D><b>{$nation['name']}</b></>{$josaYi} 전토를 통일하였습니다. <span class='hidden_but_copyable'>(서버시드: {$hiddenSeed})</span>"];
|
||||
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
|
||||
|
||||
//연감 월결산
|
||||
|
||||
+12
-10
@@ -32,6 +32,7 @@ if ($session->userGrade < 5 && !$allowReset) {
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
|
||||
<?= WebUtil::printCSS('css/install.css') ?>
|
||||
<?= WebUtil::printDist('vue', [], true) ?>
|
||||
<?= WebUtil::printDist('ts', ['common', 'install']) ?>
|
||||
</head>
|
||||
|
||||
@@ -92,8 +93,8 @@ if ($session->userGrade < 5 && !$allowReset) {
|
||||
<label for="fiction" class="col-sm-3 col-form-label">NPC 상성</label>
|
||||
<div class="col-sm-9">
|
||||
<div id="fiction" class="btn-group btn-group-toggle" data-bs-toggle="buttons">
|
||||
<input type="radio" id="fiction_0" class="btn-check" name="fiction" value="0" checked><label for="fiction_0" class="btn btn-secondary"> 연의 </label>
|
||||
<input type="radio" id="fiction_1" class="btn-check" name="fiction" value="1"><label for="fiction_1" class="btn btn-secondary"> 가상 </label>
|
||||
<input type="radio" id="fiction_0" class="btn-check" name="fiction" value="0"><label for="fiction_0" class="btn btn-secondary"> 연의 </label>
|
||||
<input type="radio" id="fiction_1" class="btn-check" name="fiction" value="1" checked><label for="fiction_1" class="btn btn-secondary"> 가상 </label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -113,6 +114,7 @@ if ($session->userGrade < 5 && !$allowReset) {
|
||||
<div class="col-sm-9">
|
||||
<div id="block_general_create" class="btn-group btn-group-toggle" data-bs-toggle="buttons">
|
||||
<input type="radio" class="btn-check" id="block_general_create_0" name="block_general_create" value="0" checked><label for="block_general_create_0" class="btn btn-secondary">가능</label>
|
||||
<input type="radio" class="btn-check" id="block_general_create_2" name="block_general_create" value="2"><label for="block_general_create_2" class="btn btn-secondary">장수명무작위</label>
|
||||
<input type="radio" class="btn-check" id="block_general_create_1" name="block_general_create" value="1"><label for="block_general_create_1" class="btn btn-secondary">불가</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -134,13 +136,13 @@ if ($session->userGrade < 5 && !$allowReset) {
|
||||
<div class="col-sm-9">
|
||||
<div class="input-group">
|
||||
<div class="btn-group btn-group-toggle" data-bs-toggle="buttons">
|
||||
<input type="checkbox" id="autorun_develop" class="autorun_user_chk btn-check" data-key="develop" name="autorun_user[]" value="develop"><label class="btn btn-secondary" for="autorun_develop">내정</label>
|
||||
<input type="checkbox" id="autorun_warp" class="autorun_user_chk btn-check" data-key="warp" name="autorun_user[]" value="warp"><label class="btn btn-secondary" for="autorun_warp">순간이동</label>
|
||||
<input type="checkbox" id="autorun_recruit" class="autorun_user_chk btn-check" data-key="recruit" name="autorun_user[]" value="recruit"><label class="btn btn-secondary" for="autorun_recruit">징병</label>
|
||||
<input type="checkbox" id="autorun_recruit_high" class="autorun_user_chk btn-check" data-key="recruit_high" name="autorun_user[]" value="recruit_high"><label class="btn btn-secondary" for="autorun_recruit_high">모병</label>
|
||||
<input type="checkbox" id="autorun_train" class="autorun_user_chk btn-check" data-key="train" name="autorun_user[]" value="train"><label class="btn btn-secondary" for="autorun_train">훈사</label>
|
||||
<input type="checkbox" id="autorun_battle" class="autorun_user_chk btn-check" data-key="battle" name="autorun_user[]" value="battle"><label class="btn btn-secondary" for="autorun_battle">출병</label>
|
||||
<input type="checkbox" id="autorun_chief" class="autorun_user_chk btn-check" data-key="chief" name="autorun_user[]" value="chief"><label class="btn btn-secondary" for="autorun_chief">기본 사령턴</label>
|
||||
<input type="checkbox" id="autorun_develop" class="autorun_user_chk btn-check" data-key="develop" name="autorun_user[]" value="develop" checked><label class="btn btn-secondary" for="autorun_develop">내정</label>
|
||||
<input type="checkbox" id="autorun_warp" class="autorun_user_chk btn-check" data-key="warp" name="autorun_user[]" value="warp" checked><label class="btn btn-secondary" for="autorun_warp">순간이동</label>
|
||||
<input type="checkbox" id="autorun_recruit" class="autorun_user_chk btn-check" data-key="recruit" name="autorun_user[]" value="recruit" checked><label class="btn btn-secondary" for="autorun_recruit">징병</label>
|
||||
<input type="checkbox" id="autorun_recruit_high" class="autorun_user_chk btn-check" data-key="recruit_high" name="autorun_user[]" value="recruit_high" checked><label class="btn btn-secondary" for="autorun_recruit_high">모병</label>
|
||||
<input type="checkbox" id="autorun_train" class="autorun_user_chk btn-check" data-key="train" name="autorun_user[]" value="train" checked><label class="btn btn-secondary" for="autorun_train">훈사</label>
|
||||
<input type="checkbox" id="autorun_battle" class="autorun_user_chk btn-check" data-key="battle" name="autorun_user[]" value="battle" checked><label class="btn btn-secondary" for="autorun_battle">출병</label>
|
||||
<input type="checkbox" id="autorun_chief" class="autorun_user_chk btn-check" data-key="chief" name="autorun_user[]" value="chief" checked><label class="btn btn-secondary" for="autorun_chief">기본 사령턴</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -162,7 +164,7 @@ if ($session->userGrade < 5 && !$allowReset) {
|
||||
<option value="480">8시간</option>
|
||||
<option value="600">10시간</option>
|
||||
<option value="720">12시간</option>
|
||||
<option value="1440">24시간</option>
|
||||
<option value="1440" selected>24시간</option>
|
||||
<option value="2160">36시간</option>
|
||||
<option value="2880">48시간</option>
|
||||
<option value="3600">60시간</option>
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
@@ -100,7 +102,7 @@ if(in_array($stateOpt, ['try_destroy_src', 'try_destroy_dest'])){
|
||||
'reason'=>'파기'
|
||||
];
|
||||
}
|
||||
$msgText = "외교 서신 #{$letterNo}를 파기했습니다.";
|
||||
$msgText = "외교 서신(#{$letterNo})을 파기했습니다.";
|
||||
$lastState = 'cancelled';
|
||||
}
|
||||
else{
|
||||
@@ -114,12 +116,12 @@ else{
|
||||
'aux'=>Json::encode($aux)
|
||||
], 'no=%i', $letterNo);
|
||||
|
||||
$msgText = "외교 서신 #{$letterNo}를 파기 요청합니다.";
|
||||
$msgText = "외교 서신(#{$letterNo})을 파기 요청합니다.";
|
||||
$lastState = 'activated';
|
||||
}
|
||||
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
$msgText,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
@@ -85,7 +87,7 @@ if($isAgree){
|
||||
], 'no=%i', $prevLetterNo);
|
||||
$prevLetterNo = $db->queryFirstField('SELECT prev_no FROM ng_diplomacy WHERE state != \'cancelled\' AND no = %i', $prevLetterNo);
|
||||
}
|
||||
$msgText = "외교 서신 #{$letterNo}가 승인되었습니다.";
|
||||
$msgText = "외교 서신( #{$letterNo})이 승인되었습니다.";
|
||||
}
|
||||
else{
|
||||
$aux['reason'] = [
|
||||
@@ -97,14 +99,14 @@ else{
|
||||
'state'=>'cancelled',
|
||||
'aux'=>Json::encode($aux)
|
||||
], 'no=%i', $letterNo);
|
||||
$msgText = "외교 서신 #{$letterNo}가 거부되었습니다.";
|
||||
$msgText = "외교 서신(#{$letterNo})이 거부되었습니다.";
|
||||
if($reason){
|
||||
$msgText .= ' 이유 : '.$reason;
|
||||
}
|
||||
}
|
||||
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
$msgText,
|
||||
@@ -115,7 +117,7 @@ $msg = new Message(
|
||||
$msgID = $msg->send();
|
||||
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_NATIONAL,
|
||||
MessageType::national,
|
||||
$src,
|
||||
$dest,
|
||||
$msgText,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
@@ -70,10 +72,10 @@ $db->update('ng_diplomacy', [
|
||||
'state'=>'cancelled',
|
||||
'aux'=>Json::encode($aux)
|
||||
], 'no=%i', $letterNo);
|
||||
$msgText = "외교 서신 #{$letterNo}가 회수되었습니다.";
|
||||
$msgText = "외교 서신(#{$letterNo})이 회수되었습니다.";
|
||||
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
$msgText,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
@@ -176,7 +178,7 @@ else{
|
||||
|
||||
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
$msgText,
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@ $scenario = (int)$_POST['scenario'];
|
||||
$fiction = (int)$_POST['fiction'];
|
||||
$extend = (int)$_POST['extend'];
|
||||
$npcmode = (int)$_POST['npcmode'];
|
||||
$block_general_create = (bool)$_POST['block_general_create'];
|
||||
$block_general_create = (int)$_POST['block_general_create'];
|
||||
$show_img_level = (int)$_POST['show_img_level'];
|
||||
$tournament_trig = !!(int)$_POST['tournament_trig'];
|
||||
$join_mode = $_POST['join_mode'];
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include('lib.php');
|
||||
include('func.php');
|
||||
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
|
||||
if(!Session::getInstance()->generalID){
|
||||
Json::die([
|
||||
"nation"=>[]
|
||||
]);
|
||||
}
|
||||
|
||||
//NOTE: 모든 국가, 모든 장수에 대해서 같은 결과라면 캐싱 가능하지 않을까?
|
||||
|
||||
Json::die([
|
||||
"nation"=>getMailboxList()
|
||||
]);
|
||||
@@ -1,63 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include 'lib.php';
|
||||
include 'func.php';
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
//{msgID: 1206, response: true}
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
|
||||
|
||||
$generalID = Session::getInstance()->generalID;
|
||||
|
||||
if (!$generalID) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'로그인하지 않음'
|
||||
]);
|
||||
}
|
||||
|
||||
$jsonPost = Json::decode(Util::getPost('data', 'string', '{}'));
|
||||
|
||||
$msgID = Util::toInt($jsonPost['msgID']??null);
|
||||
$msgResponse = $jsonPost['response']??null;
|
||||
|
||||
if ($msgID === null || !is_bool($msgResponse)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 인자'
|
||||
]);
|
||||
}
|
||||
|
||||
$general = DB::db()->queryFirstRow('SELECT `no`, `name`, `nation`, `officer_level`, `npc`, `gold`, `rice`, `troop`, `aux` from `general` where `no` = %i', $generalID);
|
||||
if(!$general){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'존재하지 않는 장수'
|
||||
]);
|
||||
}
|
||||
|
||||
$msg = Message::getMessageByID($msgID);
|
||||
if($msg === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 메시지'
|
||||
]);
|
||||
}
|
||||
$reason = 'success';
|
||||
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
$gameStor->cacheAll();
|
||||
if($msgResponse){
|
||||
$result = $msg->agreeMessage($general['no'], $reason);
|
||||
}
|
||||
else{
|
||||
$result = $msg->declineMessage($general['no'], $reason);
|
||||
}
|
||||
|
||||
|
||||
Json::die([
|
||||
'result' => $result!==DiplomaticMessage::INVALID,
|
||||
'reason' => $reason
|
||||
]);
|
||||
@@ -1,74 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include('lib.php');
|
||||
include('func.php');
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$session = Session::requireGameLogin([]);
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$msgID = Util::getPost('msgID', 'int');
|
||||
if($msgID === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 범위 입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$lastMsgGet = Json::decode($session->lastMsgGet)??[];
|
||||
$now = new \DateTime();
|
||||
$delayTime = false;
|
||||
if(count($lastMsgGet) >= 10){
|
||||
try{
|
||||
if($lastMsgGet[0] !== 'string'){
|
||||
throw new \Exception('Why not string?');
|
||||
}
|
||||
$first = new \DateTime($lastMsgGet[0]);
|
||||
$diff = $first->diff($now);
|
||||
if($diff->days == 0 && $diff->h > 0 && $diff->i == 0 && $diff->s <= 5){
|
||||
$delayTime = true;
|
||||
}
|
||||
array_shift($lastMsgGet);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
$lastMsgGet = [];
|
||||
}
|
||||
}
|
||||
$lastMsgGet[] = $now;
|
||||
$session->lastMsgGet = Json::encode($lastMsgGet);
|
||||
|
||||
if($delayTime){
|
||||
sleep(1);
|
||||
}
|
||||
$session->setReadOnly();
|
||||
|
||||
list($generalID, $nationID, $generalName) = DB::db()->queryFirstList(
|
||||
'select `no`, `nation`, `name` from `general` where owner = %i',
|
||||
$userID
|
||||
);
|
||||
|
||||
if($nationID === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수가 사망했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$reason = Message::deleteMsg($msgID, $generalID);
|
||||
if($reason === null){
|
||||
$result = [
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
];
|
||||
}
|
||||
else{
|
||||
$result = [
|
||||
'result'=>false,
|
||||
'reason'=>$reason
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
Json::die($result);
|
||||
@@ -1,118 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include('lib.php');
|
||||
include('func.php');
|
||||
|
||||
$session = Session::requireGameLogin([]);
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$reqTo = Util::getPost('to', 'int');
|
||||
$reqType = Util::getPost('type', 'string');
|
||||
|
||||
if($reqTo === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 범위 입니다.'
|
||||
]);
|
||||
}
|
||||
if($reqType === null || !in_array($reqType, ['private', 'public', 'national', 'diplomacy'])){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 타입입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$lastMsgGet = Json::decode($session->lastMsgGet)??[];
|
||||
$now = new \DateTime();
|
||||
$delayTime = false;
|
||||
if(count($lastMsgGet) >= 10){
|
||||
try{
|
||||
if($lastMsgGet[0] !== 'string'){
|
||||
throw new \Exception('Why not string?');
|
||||
}
|
||||
$first = new \DateTime($lastMsgGet[0]);
|
||||
$diff = $first->diff($now);
|
||||
if($diff->days == 0 && $diff->h > 0 && $diff->i == 0 && $diff->s <= 1){
|
||||
$delayTime = true;
|
||||
}
|
||||
array_shift($lastMsgGet);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
$lastMsgGet = [];
|
||||
}
|
||||
}
|
||||
$lastMsgGet[] = $now;
|
||||
$session->lastMsgGet = Json::encode($lastMsgGet);
|
||||
|
||||
if($delayTime){
|
||||
sleep(1);
|
||||
}
|
||||
$session->setReadOnly();
|
||||
|
||||
$me = DB::db()->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
if($me === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수가 사망했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
[$generalID, $nationID, $generalName] = [$me['no'], $me['nation'], $me['name']];
|
||||
$permission = checkSecretPermission($me, false);
|
||||
|
||||
$result = [
|
||||
'private'=>[],
|
||||
'public'=>[],
|
||||
'national'=>[],
|
||||
'diplomacy'=>[],
|
||||
'result'=>true,
|
||||
'keepRecent'=>true,
|
||||
'sequence'=>0,
|
||||
'nationID'=>$nationID,
|
||||
'generalName'=>$generalName,
|
||||
];
|
||||
$result['result'] = true;
|
||||
|
||||
$nextSequence = $reqTo;
|
||||
|
||||
if($reqType == 'private'){
|
||||
$result['private'] = array_map(function(Message $msg) use (&$nextSequence){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBoxOld($generalID, Message::MSGTYPE_PRIVATE, $reqTo, 15));
|
||||
}
|
||||
else if($reqType == 'public'){
|
||||
$result['public'] = array_map(function(Message $msg)use (&$nextSequence){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBoxOld(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, $reqTo, 15));
|
||||
}
|
||||
else if($reqType == 'national'){
|
||||
$result['national'] = array_map(function(Message $msg)use (&$nextSequence){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, $reqTo, 15));
|
||||
}
|
||||
else{
|
||||
$result['diplomacy'] = array_map(function(Message $msg)use (&$nextSequence, $permission){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
$values = $msg->toArray();
|
||||
if($msg->dest->nationID != 0 && $permission < 3){
|
||||
$values['text'] = '(외교 메시지입니다)';//TODO: 외교서신이라 읽을 수 없음을 보여줘야함
|
||||
$values['option']['invalid'] = true;
|
||||
}
|
||||
return $values;
|
||||
}, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, $reqTo, 15));
|
||||
}
|
||||
|
||||
Json::die($result);
|
||||
@@ -1,120 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include('lib.php');
|
||||
include('func.php');
|
||||
|
||||
$session = Session::requireGameLogin([]);
|
||||
$userID = Session::getUserID();
|
||||
|
||||
$reqSequence = Util::getPost('sequence', 'int', -1);
|
||||
|
||||
$lastMsgGet = Json::decode($session->lastMsgGet)??[];
|
||||
$now = new \DateTime();
|
||||
$delayTime = false;
|
||||
if(count($lastMsgGet) >= 10){
|
||||
try{
|
||||
if(!is_string($lastMsgGet[0])){
|
||||
throw new \Exception('Why not string?');
|
||||
}
|
||||
$first = new \DateTime($lastMsgGet[0]);
|
||||
$diff = $first->diff($now);
|
||||
if($diff->days == 0 && $diff->h > 0 && $diff->i == 0 && $diff->s <= 1){
|
||||
$delayTime = true;
|
||||
}
|
||||
array_shift($lastMsgGet);
|
||||
}
|
||||
catch(\Exception $e){
|
||||
$lastMsgGet = [];
|
||||
}
|
||||
}
|
||||
$lastMsgGet[] = TimeUtil::now();
|
||||
$session->lastMsgGet = Json::encode($lastMsgGet);
|
||||
|
||||
if($delayTime){
|
||||
usleep(200);
|
||||
}
|
||||
$session->setReadOnly();
|
||||
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
if($me === null){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수가 사망했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
[$generalID, $nationID, $generalName] = [$me['no'], $me['nation'], $me['name']];
|
||||
$permission = checkSecretPermission($me, false);
|
||||
|
||||
$result = [];
|
||||
$result['result'] = true;
|
||||
$result['keepRecent'] = false;
|
||||
$nextSequence = $reqSequence;
|
||||
$minSequence = $reqSequence;
|
||||
$lastType = null;
|
||||
|
||||
$result['private'] = array_map(function(Message $msg) use (&$nextSequence, &$minSequence, &$lastType){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if($msg->id <= $minSequence){
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'private';
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBox($generalID, Message::MSGTYPE_PRIVATE, 15, $reqSequence));
|
||||
|
||||
$result['public'] = array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if($msg->id <= $minSequence){
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'public';
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBox(Message::MAILBOX_PUBLIC, Message::MSGTYPE_PUBLIC, 15, $reqSequence));
|
||||
|
||||
$result['national'] = array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if($msg->id <= $minSequence){
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'national';
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_NATIONAL, 15, $reqSequence));
|
||||
|
||||
$result['diplomacy']= array_map(function(Message $msg)use (&$nextSequence, &$minSequence, &$lastType, $permission){
|
||||
if($msg->id > $nextSequence){
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if($msg->id <= $minSequence){
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'diplomacy';
|
||||
}
|
||||
$values = $msg->toArray();
|
||||
if($msg->dest->nationID != 0 && $permission < 3){
|
||||
$values['text'] = '(외교 메시지입니다)';//TODO: 외교서신이라 읽을 수 없음을 보여줘야함
|
||||
$values['option']['invalid'] = true;
|
||||
}
|
||||
return $values;
|
||||
}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, Message::MSGTYPE_DIPLOMACY, 15, $reqSequence));
|
||||
|
||||
if($lastType !== null){
|
||||
array_pop($result[$lastType]);
|
||||
$result['keepRecent'] = true;
|
||||
}
|
||||
else if($reqSequence <= 0){
|
||||
$result['keepRecent'] = true;
|
||||
}
|
||||
|
||||
$result['sequence'] = $nextSequence;
|
||||
$result['nationID'] = $nationID;
|
||||
$result['generalName'] = $generalName;
|
||||
Json::die($result);
|
||||
@@ -1,206 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include 'lib.php';
|
||||
include 'func.php';
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
$post = Json::decode(Util::getPost('data', 'string', '{}'));
|
||||
'@phan-var mixed[] $post';
|
||||
|
||||
$v = new Validator($post);
|
||||
$v->rule('required', ['mailbox','text']);
|
||||
$v->rule('integer', 'mailbox');
|
||||
$v->rule('lengthMin', 'text', 1);
|
||||
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$v->errorStr(),
|
||||
'msgID'=>null
|
||||
]);
|
||||
}
|
||||
|
||||
$mailbox = (int)$post['mailbox'];
|
||||
$text = trim(StringUtil::cutStringForWidth($post['text'], 199, ''));
|
||||
|
||||
$session = Session::requireGameLogin([
|
||||
'msgID'=>null
|
||||
]);
|
||||
$userID = Session::getUserID();
|
||||
//NOTE: 전송 메시지 시간 계산을 위해 Session을 쓰기 가능 상태로 열어둠.
|
||||
|
||||
increaseRefresh('서신전달', 1);
|
||||
|
||||
if(getBlockLevel() == 1 || getBlockLevel() == 3) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '차단되었습니다.',
|
||||
'msgID'=>null
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 메시지 전송 코드.
|
||||
*
|
||||
* TODO: 장기적으로 ajax는 한곳에 모을 필요가 있을 듯.
|
||||
*/
|
||||
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission,belong FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
if(!$me){
|
||||
$session->logoutGame();
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '로그인되지 않았습니다.',
|
||||
'msgID' => null
|
||||
]);
|
||||
}
|
||||
|
||||
$con = checkLimit($me['con']);
|
||||
if($con >= 2) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '접속 제한입니다.',
|
||||
'msgID' => null
|
||||
]);
|
||||
}
|
||||
|
||||
$me['icon'] = GetImageURL($me['imgsvr'], $me['picture']);
|
||||
$permission = checkSecretPermission($me);
|
||||
$srcNation = getNationStaticInfo($me['nation']);
|
||||
|
||||
$src = new MessageTarget($me['no'], $me['name'], $srcNation['nation'], $srcNation['name'], $srcNation['color'], $me['icon']);
|
||||
|
||||
// 전체 메세지
|
||||
if($mailbox == Message::MAILBOX_PUBLIC) {
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PUBLIC,
|
||||
$src,
|
||||
$src,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
$msgID = $msg->send();
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'SUCCESS',
|
||||
'msgID' => $msgID
|
||||
]);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 국가 메세지
|
||||
if($mailbox >= Message::MAILBOX_NATIONAL) {
|
||||
|
||||
if($permission < 4){
|
||||
$destNationID = $me['nation'];
|
||||
}
|
||||
else{
|
||||
$destNationID = $mailbox - Message::MAILBOX_NATIONAL;
|
||||
}
|
||||
|
||||
if($destNationID == $me['nation']){
|
||||
$msgType = Message::MSGTYPE_NATIONAL;
|
||||
}
|
||||
else{
|
||||
$msgType = Message::MSGTYPE_DIPLOMACY;
|
||||
}
|
||||
|
||||
$destNation = getNationStaticInfo($destNationID);
|
||||
|
||||
$dest = new MessageTarget(0, '', $destNation['nation'], $destNation['name'], $destNation['color']);
|
||||
|
||||
$msg = new Message(
|
||||
$msgType,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
$msgID = $msg->send();
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'SUCCESS',
|
||||
'msgID' => $msgID
|
||||
]);
|
||||
}
|
||||
|
||||
// 개인 메세지
|
||||
if($mailbox > 0) {
|
||||
$lastMsg = new \DateTime($session->lastMsg??'0000-00-00');
|
||||
|
||||
$msg_interval = $now->getTimestamp() - $lastMsg->getTimestamp();
|
||||
//NOTE: 여기서 유저 레벨을 구별할 코드가 필요할까?
|
||||
if($msg_interval < 2){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '개인메세지는 2초당 1건만 보낼 수 있습니다!',
|
||||
'msgID' => null
|
||||
]);
|
||||
}
|
||||
|
||||
$session->lastMsg = $now->format('Y-m-d H:i:s');
|
||||
|
||||
$destUser = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,permission,penalty FROM general WHERE `no`=%i',$mailbox);
|
||||
|
||||
if(!$destUser){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '존재하지 않는 유저입니다.',
|
||||
'msgID' => null
|
||||
]);
|
||||
}
|
||||
|
||||
$destPermission = checkSecretPermission($destUser, false);
|
||||
if($permission == 4 && $destPermission == 4 && $destUser['nation'] != $me['nation']){
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '외교권자끼리는 메시지를 보낼 수 없습니다.',
|
||||
'msgID' => null
|
||||
]);
|
||||
}
|
||||
|
||||
$destNation = getNationStaticInfo($destUser['nation']);
|
||||
|
||||
$dest = new MessageTarget(
|
||||
$destUser['no'],
|
||||
$destUser['name'],
|
||||
$destNation['nation'],
|
||||
$destNation['name'],
|
||||
$destNation['color'],
|
||||
GetImageURL($destUser['imgsvr'], $destUser['picture'])
|
||||
);
|
||||
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PRIVATE,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
$msgID = $msg->send();
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reason' => 'SUCCESS',
|
||||
'msgID' => $msgID
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '알 수 없는 에러',
|
||||
'msgID' => null
|
||||
]);
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
@@ -226,8 +228,8 @@ function do추방(General $general, int $myOfficerLevel):?string{
|
||||
}
|
||||
else{
|
||||
$betrayCnt = $general->getVar('betray');
|
||||
$general->addExperience(-$general->getVar('experience')*0.1*$betrayCnt);
|
||||
$general->addDedication(-$general->getVar('dedication')*0.1*$betrayCnt);
|
||||
$general->addExperience(-$general->getVar('experience')*0.15*$betrayCnt);
|
||||
$general->addDedication(-$general->getVar('dedication')*0.15*$betrayCnt);
|
||||
$general->increaseVarWithLimit('betray', 1, null, GameConst::$maxBetrayCnt);
|
||||
}
|
||||
|
||||
@@ -268,7 +270,7 @@ function do추방(General $general, int $myOfficerLevel):?string{
|
||||
GetImageURL($general->getVar('imgsvr'), $general->getVar('picture'))
|
||||
);
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PUBLIC,
|
||||
MessageType::public,
|
||||
$src,
|
||||
$src,
|
||||
$str,
|
||||
|
||||
@@ -56,7 +56,7 @@ if(file_exists(__DIR__.'/.htaccess')){
|
||||
'scenarioName'=>$options['scenarioName'],
|
||||
'turnterm'=>$options['turnterm'],
|
||||
'fictionMode'=>($options['fiction']?'가상':'사실'),
|
||||
'block_general_create'=>(!!$options['block_general_create']),
|
||||
'block_general_create'=>Util::toInt($options['block_general_create']),
|
||||
'npcMode'=>([0=>'불가',1=>'가능',2=>'선택 생성'][$options['npcmode']]),
|
||||
'openDatetime'=>$reserved['date'],
|
||||
'starttime'=>$options['starttime'],
|
||||
@@ -90,7 +90,7 @@ $admin['scenario'] = $admin['scenario_text'];
|
||||
$admin['userCnt'] = $genCnt;
|
||||
$admin['npcCnt'] = $npcCnt;
|
||||
$admin['nationCnt'] = $nationCnt;
|
||||
$admin['block_general_create'] = !!$admin['block_general_create'];
|
||||
$admin['block_general_create'] = $admin['block_general_create'];
|
||||
$admin['npcMode'] = [0=>'불가',1=>'가능',2=>'선택 생성'][$admin['npcMode']];
|
||||
$admin['fictionMode'] = $admin['fiction']?'가상':'사실';
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ if($defence_train !== $me->getVar('defence_train')){
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
$me->increaseVarWithLimit('train', -3, 20);
|
||||
$me->increaseVarWithLimit('atmos', -3, 20);
|
||||
$me->increaseVarWithLimit('atmos', -6, 20);
|
||||
}
|
||||
else{
|
||||
$me->increaseVar('myset', -1);
|
||||
|
||||
@@ -82,7 +82,7 @@ function applyNationPolicy($policy, $nationID, $generalName): ?string
|
||||
return "{$troopID}는 국가의 부대가 아닙니다.";
|
||||
}
|
||||
if ($troopCache[$troopID] != 'Neutral') {
|
||||
return "부대({$troopID}는 하나의 역할만 지정할 수 있습니다.";
|
||||
return "부대({$troopID})는 하나의 역할만 지정할 수 있습니다.";
|
||||
}
|
||||
if (!is_array($troopTarget) || count($troopTarget) != 2) {
|
||||
return "{$troopID}의 입력양식이 올바르지 않습니다.";
|
||||
|
||||
@@ -84,6 +84,7 @@ $rawDefenderList = $query['defenderGenerals'];
|
||||
$rawDefenderCity = $query['defenderCity'];
|
||||
$rawDefenderNation = $query['defenderNation'];
|
||||
|
||||
$warSeed = $query['seed'] ?? '';
|
||||
|
||||
$generalCheck = [
|
||||
'required'=>[
|
||||
@@ -132,6 +133,19 @@ $generalCheck = [
|
||||
['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'])],
|
||||
],
|
||||
'array'=>['inheritBuff'],
|
||||
];
|
||||
|
||||
$inheritBuffCheck = [
|
||||
'between'=>[
|
||||
[TriggerInheritBuff::WAR_AVOID_RATIO, [0, 5]],
|
||||
[TriggerInheritBuff::WAR_CRITICAL_RATIO, [0, 5]],
|
||||
[TriggerInheritBuff::WAR_MAGIC_TRIAL_PROB, [0, 5]],
|
||||
|
||||
[TriggerInheritBuff::OPPOSE_WAR_AVOID_RATIO, [0, 5]],
|
||||
[TriggerInheritBuff::OPPOSE_WAR_CRITICAL_RATIO, [0, 5]],
|
||||
[TriggerInheritBuff::OPPOSE_WAR_MAGIC_TRIAL_PROB, [0, 5]],
|
||||
]
|
||||
];
|
||||
|
||||
@@ -143,6 +157,19 @@ if(!$v->validate()){
|
||||
'reason'=>'[출병자]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$rawAttacker['aux'] = [];
|
||||
if(key_exists('inheritBuff', $rawAttacker)){
|
||||
$v = new Validator($rawAttacker['inheritBuff']);
|
||||
$v->rules($inheritBuffCheck);
|
||||
if(!$v->validate()){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'[출병자]'.$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$rawAttacker['aux']['inheritBuff'] = $rawAttacker['inheritBuff'];
|
||||
}
|
||||
$rawAttacker['aux'] = Json::encode($rawAttacker['aux']);
|
||||
$rawAttacker['owner'] = 0;
|
||||
|
||||
$defenderList = [];
|
||||
@@ -156,6 +183,20 @@ foreach($rawDefenderList as $idx=>$rawDefenderGeneral){
|
||||
'reason'=>"[수비자{$idx}]".$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$rawDefenderGeneral['aux'] = [];
|
||||
if(key_exists('inheritBuff', $rawDefenderGeneral)){
|
||||
$v = new Validator($rawDefenderGeneral['inheritBuff']);
|
||||
$v->rules($inheritBuffCheck);
|
||||
if(!$v->validate()){
|
||||
$idx+=1;
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>"[수비자{$idx}]".$v->errorStr()
|
||||
]);
|
||||
}
|
||||
$rawDefenderGeneral['aux']['inheritBuff'] = $rawDefenderGeneral['inheritBuff'];
|
||||
}
|
||||
$rawDefenderGeneral['aux'] = Json::encode($rawDefenderGeneral['aux']);
|
||||
$rawDefenderGeneral['owner'] = 0;
|
||||
|
||||
$defenderList[] = new General($rawDefenderGeneral, extractRankVar($rawDefenderGeneral), $rawDefenderCity, $rawAttackerNation, $year, $month, true);
|
||||
@@ -281,7 +322,6 @@ 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):Map{
|
||||
$rankVars = new Map;
|
||||
@@ -298,10 +338,13 @@ function extractRankVar(array $rawVal):Map{
|
||||
function simulateBattle(
|
||||
$rawAttacker, $rawAttackerCity, $rawAttackerNation,
|
||||
$rawDefenderList, $rawDefenderCity, $rawDefenderNation,
|
||||
$startYear, $year, $month, $cityRate
|
||||
$startYear, $year, $month, $warSeed
|
||||
){
|
||||
|
||||
$warSeed = bin2hex(random_bytes(16));
|
||||
if(!$warSeed){
|
||||
$warSeed = bin2hex(random_bytes(16));
|
||||
}
|
||||
|
||||
$warRng = new RandUtil(new LiteHashDRBG($warSeed));
|
||||
|
||||
$attacker = new WarUnitGeneral(
|
||||
@@ -310,7 +353,7 @@ function simulateBattle(
|
||||
$rawAttackerNation,
|
||||
true
|
||||
);
|
||||
$city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate);
|
||||
$city = new WarUnitCity($warRng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
|
||||
|
||||
$iterDefender = new \ArrayIterator($rawDefenderList);
|
||||
$iterDefender->rewind();
|
||||
@@ -367,7 +410,7 @@ function simulateBattle(
|
||||
$rice = $city->getKilled() / 100 * 0.8;
|
||||
$rice *= $city->getCrewType()->rice;
|
||||
$rice *= getTechCost($rawDefenderNation['tech']);
|
||||
$rice *= $cityRate / 100 - 0.2;
|
||||
$rice *= $city->getCityTrainAtmos() / 100 - 0.2;
|
||||
Util::setRound($rice);
|
||||
|
||||
$defenderRice += $rice;
|
||||
@@ -401,12 +444,16 @@ $avgWar = 0;
|
||||
$attackerActivatedSkills = [];
|
||||
$defendersActivatedSkills = [];
|
||||
|
||||
if($warSeed){
|
||||
$repeatCnt = 1;
|
||||
}
|
||||
|
||||
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
|
||||
$startYear, $year, $month, $warSeed
|
||||
);
|
||||
$lastWarLog = Util::mapWithKey(function($key, $values){
|
||||
return ConvertLog(join('<br>', $values));
|
||||
|
||||
-146
@@ -1,146 +0,0 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
// $btn, $name, $troop
|
||||
$action = Util::getPost('action');
|
||||
$name = Util::getPost('name');
|
||||
$gen = Util::getPost('gen', 'int');
|
||||
$troop = Util::getPost('troop', 'int');
|
||||
|
||||
//로그인 검사
|
||||
$session = Session::requireGameLogin([])->setReadOnly();
|
||||
$userID = $session::getUserID();
|
||||
|
||||
increaseRefresh("부대명령", 0);
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$me = $db->queryFirstRow('SELECT `no`, name, nation, troop FROM general WHERE `owner`=%i', $userID);
|
||||
$generalID = $me['no'];
|
||||
$nationID = $me['nation'];
|
||||
|
||||
if($action == '부대창설'){
|
||||
$name = StringUtil::neutralize($name);
|
||||
if(!$name){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부대 이름이 없습니다.'
|
||||
]);
|
||||
}
|
||||
if($me['troop'] != 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'이미 부대에 가입해있습니다.'
|
||||
]);
|
||||
}
|
||||
$db->insert('troop',[
|
||||
'troop_leader'=>$generalID,
|
||||
'name'=>$name,
|
||||
'nation'=>$nationID,
|
||||
]);
|
||||
|
||||
$db->update('general', [
|
||||
'troop'=>$generalID,
|
||||
], 'no=%i',$generalID);
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
if($action == '부대추방'){
|
||||
if (!$gen){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'장수를 지정해야 합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$db->update('general', [
|
||||
'troop'=>0
|
||||
], 'no=%i AND troop = %i', $gen, $generalID);
|
||||
|
||||
if($db->affectedRows() == 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부대장이 아니거나, 장수를 잘못 지정했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
if ($action == '부대가입') {
|
||||
if(!$troop){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부대를 지정해야 합니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($me['troop'] === $generalID){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부대장입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$troopExists = $db->queryFirstField('SELECT `troop_leader` FROM `troop` WHERE `troop_leader` = %i AND `nation` = %i', $troop, $nationID);
|
||||
|
||||
if (!$troopExists) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 부대장이 아닙니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$db->update('general', [
|
||||
'troop'=>$troop
|
||||
], 'no=%i', $generalID);
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
if($action == "부대탈퇴") {
|
||||
|
||||
if($me['troop'] == 0){
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'부대에 속해있지 않습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
//부대장일 경우
|
||||
if($me['troop'] === $generalID){
|
||||
$db->update('general', [
|
||||
'troop'=>0
|
||||
], 'troop=%i',$generalID);
|
||||
$db->delete('troop', 'troop_leader=%i', $generalID);
|
||||
}
|
||||
else{
|
||||
$db->update('general', [
|
||||
'troop'=>0
|
||||
], 'no=%i', $generalID);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success'
|
||||
]);
|
||||
}
|
||||
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바르지 않은 명령입니다.'
|
||||
]);
|
||||
+2
-2
@@ -63,8 +63,8 @@ function prepareDir(string $dirPath, bool $forceCreate=true):bool{
|
||||
if(!unlink($dirPath)){
|
||||
return false;
|
||||
}
|
||||
return mkdir($dirPath);
|
||||
return mkdir($dirPath, 0775);
|
||||
}
|
||||
|
||||
return mkdir($dirPath, 0777, true);
|
||||
return mkdir($dirPath, 0775, true);
|
||||
}
|
||||
+5
-6
@@ -29,11 +29,11 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
||||
}
|
||||
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
[$startYear, $year, $month, $cityRate, $joinMode] = $gameStor->getValuesAsArray(['startyear', 'year', 'month', 'city_rate', 'join_mode']);
|
||||
[$startYear, $year, $month, $joinMode] = $gameStor->getValuesAsArray(['startyear', 'year', 'month', 'join_mode']);
|
||||
|
||||
$attacker = new WarUnitGeneral($rng, $attackerGeneral,$rawAttackerNation, true);
|
||||
|
||||
$city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $cityRate);
|
||||
$city = new WarUnitCity($rng, $rawDefenderCity, $rawDefenderNation, $year, $month, $startYear);
|
||||
|
||||
$defenderIDList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND city=%i AND nation!=0 and crew > 0 and rice>(crew/100) and train>=defence_train and atmos>=defence_train', $city->getVar('nation'), $city->getVar('city'));
|
||||
$defenderList = General::createGeneralObjListFromDB($defenderIDList, null, 2);
|
||||
@@ -90,7 +90,7 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
||||
$rice = $city->getKilled() / 100 * 0.8;
|
||||
$rice *= $city->getCrewType()->rice;
|
||||
$rice *= getTechCost($rawDefenderNation['tech']);
|
||||
$rice *= $cityRate / 100 - 0.2;
|
||||
$rice *= $city->getCityTrainAtmos() / 100 - 0.2;
|
||||
Util::setRound($rice);
|
||||
|
||||
$updateDefenderNation['rice'] = max(0, $rawDefenderNation['rice'] - $rice);
|
||||
@@ -113,8 +113,8 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
||||
'dead' => $db->sqleval('dead + %i', $totalDead * 0.6)
|
||||
], 'city=%i', $rawDefenderCity['city']);
|
||||
|
||||
$attackerIncTech = buildNationTypeClass($rawAttackerNation['type'])->onCalcDomestic('기술', 'score', $attacker->getDead() * 0.01);
|
||||
$defenderIncTech = buildNationTypeClass($rawDefenderNation['type'])->onCalcDomestic('기술', 'score', $attacker->getKilled() * 0.01);
|
||||
$attackerIncTech = buildNationTypeClass($rawAttackerNation['type'])->onCalcDomestic('기술', 'score', $attacker->getDead() * 0.012);
|
||||
$defenderIncTech = buildNationTypeClass($rawDefenderNation['type'])->onCalcDomestic('기술', 'score', $attacker->getKilled() * 0.009);
|
||||
|
||||
$attackerGenCnt = $rawAttackerNation['gennum'];
|
||||
$defenderGenCnt = $rawDefenderNation['gennum'];
|
||||
@@ -175,7 +175,6 @@ function processWar(string $warSeed, General $attackerGeneral, array $rawAttacke
|
||||
'startyear' => $startYear,
|
||||
'year' => $year,
|
||||
'month' => $month,
|
||||
'city_rate' => $cityRate,
|
||||
'join_mode' => $joinMode,
|
||||
], $attacker->getGeneral(), $city->getRaw());
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ include "func.php";
|
||||
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
|
||||
<?= WebUtil::printCSS('css/map.css') ?>
|
||||
<?= WebUtil::printDist('ts', ['common', 'recent_map'], true) ?>
|
||||
<?= WebUtil::printDist('vue', [], true) ?>
|
||||
<style>
|
||||
html {
|
||||
width: 700px;
|
||||
|
||||
@@ -26,7 +26,7 @@ class Bet extends \sammo\BaseAPI
|
||||
->rule('int', 'bettingID')
|
||||
->rule('integerArray', 'bettingType')
|
||||
->rule('int', 'amount')
|
||||
->rule('min', 'amount', 1);
|
||||
->rule('min', 'amount', 10);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
|
||||
@@ -4,7 +4,7 @@ namespace sammo\API\General;
|
||||
|
||||
use sammo\DB;
|
||||
use sammo\DummyGeneral;
|
||||
|
||||
use sammo\GameConst;
|
||||
use sammo\Session;
|
||||
use sammo\General;
|
||||
use sammo\JosaUtil;
|
||||
@@ -54,7 +54,7 @@ class DieOnPrestart extends \sammo\BaseAPI
|
||||
}
|
||||
|
||||
//서버 가오픈시 할 수 있는 행동
|
||||
$targetTime = addTurn($general['lastrefresh'], $gameStor->turnterm, 2);
|
||||
$targetTime = addTurn($general['lastrefresh'], $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
|
||||
if ($targetTime > TimeUtil::now()) {
|
||||
$targetTimeShort = substr($targetTime, 0, 19);
|
||||
return "아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다.";
|
||||
@@ -67,7 +67,7 @@ class DieOnPrestart extends \sammo\BaseAPI
|
||||
|
||||
$generalName = $generalObj->getName();
|
||||
$josaYi = JosaUtil::pick($generalName, '이');
|
||||
$generalObj->kill($db, true, "<Y>{$generalName}</>{$josaYi} 이 홀연히 모습을 <R>감추었습니다</>");
|
||||
$generalObj->kill($db, true, "<Y>{$generalName}</>{$josaYi} 홀연히 모습을 <R>감추었습니다</>");
|
||||
|
||||
$session->logoutGame();
|
||||
return null;
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
|
||||
namespace sammo\API\General;
|
||||
|
||||
use Ds\Set;
|
||||
use sammo\ActionLogger;
|
||||
use sammo\Auction;
|
||||
use sammo\CityConst;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\RankColumn;
|
||||
@@ -84,6 +86,40 @@ class Join extends \sammo\BaseAPI
|
||||
return static::REQ_LOGIN | static::REQ_READ_ONLY;
|
||||
}
|
||||
|
||||
public function calcRestInheritPoint(int $userID): int
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
if (Util::toInt(UniqueConst::$seasonIdx) < 1) {
|
||||
//이벤트 시즌은 카운트하지 않음
|
||||
return 0;
|
||||
}
|
||||
|
||||
$gameID = UniqueConst::$serverID;
|
||||
$alreadyJoined = $db->queryFirstField('SELECT count(*) FROM `storage` WHERE `namespace` = %s AND `key` LIKE %s', 'inheritance_result', "{$gameID}_{$userID}_%");
|
||||
if ($alreadyJoined) {
|
||||
//이미 받았음
|
||||
return 0;
|
||||
}
|
||||
|
||||
$targetBonusPointCnt = 0;
|
||||
//정상적으로 끝난 깃수만 제공
|
||||
$oldGames = $db->queryFirstColumn('SELECT server_id FROM ng_games WHERE `winner_nation` IS NOT NULL AND `season` >= 1 AND `server_id` != %s ORDER BY `date` DESC LIMIT 8', $gameID);
|
||||
|
||||
if(!$oldGames){
|
||||
return 0;
|
||||
}
|
||||
//이전에 장수를 생성한 적이 있는지
|
||||
$oldGamesCnt = new Set($db->queryFirstColumn('SELECT `server_id` FROM ng_old_generals WHERE server_id IN %ls AND `owner` = %i GROUP BY `server_id`', $oldGames, $userID));
|
||||
foreach ($oldGames as $oldGameID) {
|
||||
if($oldGamesCnt->contains($oldGameID)) {
|
||||
break;
|
||||
}
|
||||
$targetBonusPointCnt += 1;
|
||||
}
|
||||
return $targetBonusPointCnt;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?\DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$userID = $session->userID;
|
||||
@@ -105,7 +141,7 @@ class Join extends \sammo\BaseAPI
|
||||
$inheritCity = $this->args['inheritCity'] ?? null;
|
||||
$inheritBonusStat = $this->args['inheritBonusStat'] ?? null;
|
||||
|
||||
if($inheritTurntime !== null && $inheritCity !== null){
|
||||
if ($inheritTurntime !== null && $inheritCity !== null) {
|
||||
return '턴과 도시를 동시에 지정할 수 없습니다.';
|
||||
}
|
||||
|
||||
@@ -119,9 +155,16 @@ class Join extends \sammo\BaseAPI
|
||||
|
||||
$db = DB::db();
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env');
|
||||
$gameStor->cacheValues(['year', 'month', 'maxgeneral', 'scenario', 'show_img_level', 'turnterm', 'turntime', 'genius', 'npcmode']);
|
||||
$gameStor->cacheValues(['year', 'month', 'maxgeneral', 'scenario', 'show_img_level', 'block_general_create', 'turnterm', 'turntime', 'genius', 'npcmode']);
|
||||
########## 동일 정보 존재여부 확인. ##########
|
||||
|
||||
$block_general_create = $gameStor->getValue('block_general_create');
|
||||
if($block_general_create & 1){
|
||||
return '장수 직접 생성이 불가능한 모드입니다.';
|
||||
}
|
||||
|
||||
$blockCustomGeneralName = $gameStor->getValue('block_general_create') & 2;
|
||||
|
||||
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
|
||||
$oldGeneral = $db->queryFirstField('SELECT `no` FROM general WHERE `owner`=%i', $userID);
|
||||
$oldName = $db->queryFirstField('SELECT `no` FROM general WHERE `name`=%s', $name);
|
||||
@@ -305,7 +348,7 @@ class Join extends \sammo\BaseAPI
|
||||
if ($inheritTurntime !== null) {
|
||||
$inheritTurntime = $inheritTurntime % ($admin['turnterm'] * 60);
|
||||
|
||||
$userLogger->push(sprintf("턴 시간 %02d:%02d 로 지정", intdiv($inheritTurntime, 60), $inheritTurntime%60), "inheritPoint");
|
||||
$userLogger->push(sprintf("턴 시간 %02d:%02d 로 지정", intdiv($inheritTurntime, 60), $inheritTurntime % 60), "inheritPoint");
|
||||
|
||||
$inheritTurntime += $rng->nextRangeInt(0, 999999) / 1000000;
|
||||
$turntime = new \DateTimeImmutable(cutTurn($admin['turntime'], $admin['turnterm']));
|
||||
@@ -337,6 +380,15 @@ class Join extends \sammo\BaseAPI
|
||||
//상성 랜덤
|
||||
$affinity = $rng->nextRangeInt(1, 150);
|
||||
|
||||
$betray = 0;
|
||||
if ($relYear >= 4) {
|
||||
$betray += 2;
|
||||
}
|
||||
|
||||
if($blockCustomGeneralName){
|
||||
$name = bin2hex(random_bytes(5));
|
||||
}
|
||||
|
||||
########## 회원정보 테이블에 입력값을 등록한다. ##########
|
||||
$db->insert('general', [
|
||||
'owner' => $userID,
|
||||
@@ -365,6 +417,7 @@ class Join extends \sammo\BaseAPI
|
||||
'lastrefresh' => $now,
|
||||
'crewtype' => GameUnitConst::DEFAULT_CREWTYPE,
|
||||
'makelimit' => 0,
|
||||
'betray' => $betray,
|
||||
'age' => $age,
|
||||
'startage' => $age,
|
||||
'personal' => $character,
|
||||
@@ -374,6 +427,15 @@ class Join extends \sammo\BaseAPI
|
||||
'special2' => $special2
|
||||
]);
|
||||
$generalID = $db->insertId();
|
||||
|
||||
if($blockCustomGeneralName){
|
||||
//XXX: 클래스가 이게 맞나?
|
||||
$name = Auction::genObfuscatedName($generalID);
|
||||
$db->update('general', [
|
||||
'name' => $name
|
||||
], 'no=%i', $generalID);
|
||||
}
|
||||
|
||||
$turnRows = [];
|
||||
foreach (Util::range(GameConst::$maxTurn) as $turnIdx) {
|
||||
$turnRows[] = [
|
||||
@@ -402,19 +464,25 @@ class Join extends \sammo\BaseAPI
|
||||
if ($inheritRequiredPoint > 0) {
|
||||
$userLogger->push("장수 생성으로 포인트 {$inheritRequiredPoint} 소모", "inheritPoint");
|
||||
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
|
||||
$inheritStor->setValue('previous', [$inheritTotalPoint - $inheritRequiredPoint, null]);
|
||||
$inheritTotalPoint -= $inheritRequiredPoint;
|
||||
$inheritStor->setValue('previous', [$inheritTotalPoint, null]);
|
||||
$userLogger->flush();
|
||||
$db->update('rank_data', [
|
||||
'value'=>$db->sqleval('value + %i', $inheritRequiredPoint)
|
||||
'value' => $db->sqleval('value + %i', $inheritRequiredPoint)
|
||||
], 'general_id = %i AND type = %s', $generalID, RankColumn::inherit_point_spent_dynamic->value);
|
||||
}
|
||||
|
||||
$me = [
|
||||
'no' => $generalID
|
||||
];
|
||||
|
||||
$log = [];
|
||||
$mylog = [];
|
||||
$restInheritPoint = $this->calcRestInheritPoint($userID) * 500;
|
||||
if($restInheritPoint > 0){
|
||||
$userLogger->push("신규/복귀 생성으로 포인트 {$restInheritPoint} 지급", "inheritPoint");
|
||||
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
|
||||
$inheritTotalPoint += $restInheritPoint;
|
||||
$inheritStor->setValue('previous', [$inheritTotalPoint, null]);
|
||||
$userLogger->flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
$logger = new ActionLogger($generalID, 0, $gameStor->year, $gameStor->month);
|
||||
|
||||
|
||||
@@ -3,8 +3,10 @@
|
||||
namespace sammo\API\Global;
|
||||
|
||||
use sammo\Session;
|
||||
use sammo\DB;
|
||||
use DateTimeInterface;
|
||||
use sammo\TurnExecutionHelper;
|
||||
use sammo\UniqueConst;
|
||||
|
||||
class ExecuteEngine extends \sammo\BaseAPI
|
||||
{
|
||||
@@ -20,10 +22,23 @@ class ExecuteEngine extends \sammo\BaseAPI
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$updated = TurnExecutionHelper::executeAllCommand();
|
||||
$reqServerID = $this->args['serverID'] ?? null;
|
||||
if($reqServerID && $reqServerID !== UniqueConst::$serverID){
|
||||
return [
|
||||
'result' => false,
|
||||
'reason' => '서버 아이디가 다릅니다',
|
||||
'reqRefresh' => true,
|
||||
];
|
||||
}
|
||||
|
||||
$updated = false;
|
||||
$locked = false;
|
||||
$lastExecuted = TurnExecutionHelper::executeAllCommand($updated, $locked);
|
||||
return [
|
||||
'result' => true,
|
||||
'updated' => $updated,
|
||||
'locked' => $locked,
|
||||
'lastExecuted' => $lastExecuted,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Global;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
class GetRecentRecord extends \sammo\BaseAPI
|
||||
{
|
||||
|
||||
const ROW_LIMIT = 15;
|
||||
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('int', 'lastGeneralRecordID')
|
||||
->rule('int', 'lastWorldHistoryID');
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
$this->args['lastGeneralRecordID'] = (int)($this->args['lastGeneralRecordID']??0);
|
||||
$this->args['lastWorldHistoryID'] = (int)($this->args['lastWorldHistoryID']??0);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||
}
|
||||
|
||||
private function getGlobalRecord(int $lastRecordID): array
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$globalRecord = $db->queryAllLists(
|
||||
'SELECT id, `text` FROM general_record WHERE `general_id` = 0 AND log_type = %s AND id >= %i ORDER BY `id` DESC LIMIT %i',
|
||||
'history',
|
||||
$lastRecordID,
|
||||
static::ROW_LIMIT + 1,
|
||||
);
|
||||
return $globalRecord;
|
||||
}
|
||||
|
||||
private function getGeneralRecord(int $generalID, int $lastRecordID): array
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$generalRecord = $db->queryAllLists(
|
||||
'SELECT id, `text` FROM general_record WHERE `general_id` = %i AND log_type = %s AND id >= %i ORDER BY `id` DESC LIMIT %i',
|
||||
$generalID,
|
||||
'action',
|
||||
$lastRecordID,
|
||||
static::ROW_LIMIT + 1,
|
||||
);
|
||||
return $generalRecord;
|
||||
}
|
||||
|
||||
private function getHistory(int $lastHistoryID): array
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$history = $db->queryAllLists(
|
||||
'SELECT id, `text` FROM world_history WHERE nation_id = 0 AND id >= %i ORDER BY `id` DESC LIMIT %i',
|
||||
$lastHistoryID,
|
||||
static::ROW_LIMIT + 1,
|
||||
);
|
||||
return $history;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$lastHistoryID = $this->args['lastWorldHistoryID'];
|
||||
$lastRecordID = $this->args['lastGeneralRecordID'];
|
||||
|
||||
$history = $this->getHistory($lastHistoryID);
|
||||
$globalRecord = $this->getGlobalRecord($lastRecordID);
|
||||
$generalRecord = $this->getGeneralRecord($session->generalID, $lastRecordID);
|
||||
|
||||
$flushHistory = true;
|
||||
$flushGlobalRecord = true;
|
||||
$flushGeneralRecord = true;
|
||||
|
||||
if($history){
|
||||
if(Util::array_last($history)[0] == $lastHistoryID){
|
||||
$flushHistory = false;
|
||||
array_pop($history);
|
||||
}
|
||||
else if(count($history) > static::ROW_LIMIT){
|
||||
array_pop($history);
|
||||
}
|
||||
}
|
||||
|
||||
if($globalRecord){
|
||||
if(Util::array_last($globalRecord)[0] == $lastRecordID){
|
||||
$flushGlobalRecord = false;
|
||||
array_pop($globalRecord);
|
||||
}
|
||||
else if(count($globalRecord) > static::ROW_LIMIT){
|
||||
array_pop($globalRecord);
|
||||
}
|
||||
}
|
||||
|
||||
if($generalRecord){
|
||||
if(Util::array_last($generalRecord)[0] == $lastRecordID){
|
||||
$flushGeneralRecord = false;
|
||||
array_pop($generalRecord);
|
||||
}
|
||||
else if(count($generalRecord) > static::ROW_LIMIT){
|
||||
array_pop($generalRecord);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'result' => true,
|
||||
'history' => $history,
|
||||
'global' => $globalRecord,
|
||||
'general' => $generalRecord,
|
||||
'flushHistory' => $flushHistory?1:0,
|
||||
'flushGlobal' => $flushGlobalRecord?1:0,
|
||||
'flushGeneral' => $flushGeneralRecord?1:0,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Message;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\DiplomaticMessage;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Message;
|
||||
use sammo\Validator;
|
||||
|
||||
class DecideMessageResponse extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', ['msgID', 'response']);
|
||||
$v->rule('integer', 'msgID')
|
||||
->rule('boolean', 'response');
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
$this->args['msgID'] = (int)($this->args['msgID'] ?? -1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$msgID = $this->args['msgID'];
|
||||
$msgResponse = $this->args['response'];
|
||||
|
||||
$generalID = $session->generalID;
|
||||
|
||||
$msg = Message::getMessageByID($msgID);
|
||||
if ($msg === null) {
|
||||
return '존재하지 않는 메시지입니다.';
|
||||
}
|
||||
|
||||
$reason = 'success';
|
||||
$gameStor = KVStorage::getStorage(DB::db(), 'game_env');
|
||||
$gameStor->cacheAll();
|
||||
if ($msgResponse) {
|
||||
$result = $msg->agreeMessage($generalID, $reason);
|
||||
} else {
|
||||
$result = $msg->declineMessage($generalID, $reason);
|
||||
}
|
||||
|
||||
|
||||
return [
|
||||
'result' => $result !== DiplomaticMessage::INVALID,
|
||||
'reason' => $reason
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Message;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\Message;
|
||||
use sammo\Validator;
|
||||
|
||||
class DeleteMessage extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', ['msgID']);
|
||||
$v->rule('integer', 'msgID');
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
$this->args['msgID'] = (int)($this->args['msgID'] ?? -1);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$msgID = $this->args['msgID'];
|
||||
|
||||
$generalID = $session->generalID;
|
||||
return Message::deleteMsg($msgID, $generalID);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Message;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
|
||||
use function sammo\getMailboxList;
|
||||
|
||||
class GetContactList extends \sammo\BaseAPI{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN | static::REQ_READ_ONLY;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
if(!$session->generalID){
|
||||
return [
|
||||
"nation"=>[]
|
||||
];
|
||||
}
|
||||
|
||||
//NOTE: 모든 국가, 모든 장수에 대해서 같은 결과라면 캐싱 가능하지 않을까?
|
||||
|
||||
return [
|
||||
"nation"=>getMailboxList()
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Message;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Json;
|
||||
use sammo\Message;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
use function sammo\checkSecretPermission;
|
||||
|
||||
class GetOldMessage extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', [
|
||||
'to',
|
||||
'type',
|
||||
])->rule('integer', 'to')
|
||||
->rule('in', 'type', ['private', 'public', 'national', 'diplomacy']);
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
$this->args['to'] = (int)($this->args['to'] ?? 0);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
private function delayFrequentCall(Session $session): void
|
||||
{
|
||||
$lastMsgGet = Json::decode($session->lastMsgGet) ?? [];
|
||||
$now = new \DateTimeImmutable();
|
||||
$delayTime = false;
|
||||
|
||||
if (count($lastMsgGet) >= 10) {
|
||||
try {
|
||||
if (!is_string($lastMsgGet[0])) {
|
||||
throw new \Exception('Why not string?');
|
||||
}
|
||||
$first = new \DateTimeImmutable($lastMsgGet[0]);
|
||||
$diffSec = TimeUtil::DateIntervalToSeconds($first->diff($now));
|
||||
if ($diffSec < 1) {
|
||||
$delayTime = true;
|
||||
}
|
||||
array_shift($lastMsgGet);
|
||||
} catch (\Exception $e) {
|
||||
$lastMsgGet = [];
|
||||
}
|
||||
}
|
||||
$lastMsgGet[] = TimeUtil::format($now, true);
|
||||
$session->lastMsgGet = Json::encode($lastMsgGet);
|
||||
|
||||
if ($delayTime) {
|
||||
usleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$this->delayFrequentCall($session);
|
||||
$session->setReadOnly();
|
||||
$userID = $session->getUserID();
|
||||
|
||||
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
if ($me === null) {
|
||||
return '장수가 사망했습니다.';
|
||||
}
|
||||
|
||||
[$generalID, $nationID, $generalName] = [$me['no'], $me['nation'], $me['name']];
|
||||
$permission = checkSecretPermission($me, false);
|
||||
$reqTo = $this->args['to'];
|
||||
|
||||
$result = [
|
||||
MessageType::private->value => [],
|
||||
MessageType::public->value => [],
|
||||
MessageType::national->value => [],
|
||||
MessageType::diplomacy->value => [],
|
||||
'result' => true,
|
||||
'keepRecent' => true,
|
||||
'sequence' => 0,
|
||||
'nationID' => $nationID,
|
||||
'generalName' => $generalName,
|
||||
];
|
||||
$result['result'] = true;
|
||||
|
||||
$nextSequence = $reqTo;
|
||||
$reqType = MessageType::tryFrom($this->args['type']);
|
||||
if ($reqType === null) {
|
||||
return '잘못된 요청입니다.';
|
||||
}
|
||||
|
||||
if ($reqType === MessageType::private) {
|
||||
$result[MessageType::private->value] = array_map(function (Message $msg) use (&$nextSequence) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBoxOld($generalID, MessageType::private, $reqTo, 15));
|
||||
} else if ($reqType === MessageType::public) {
|
||||
$result[MessageType::public->value] = array_map(function (Message $msg) use (&$nextSequence) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBoxOld(Message::MAILBOX_PUBLIC, MessageType::public, $reqTo, 15));
|
||||
} else if ($reqType === MessageType::national) {
|
||||
$result[MessageType::national->value] = array_map(function (Message $msg) use (&$nextSequence) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, MessageType::national, $reqTo, 15));
|
||||
} else {
|
||||
$result[MessageType::diplomacy->value] = array_map(function (Message $msg) use (&$nextSequence, $permission) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
$values = $msg->toArray();
|
||||
if ($msg->dest->nationID != 0 && $permission < 3) {
|
||||
$values['text'] = '(외교 메시지입니다)'; //TODO: 외교서신이라 읽을 수 없음을 보여줘야함
|
||||
$values['option']['invalid'] = true;
|
||||
}
|
||||
return $values;
|
||||
}, Message::getMessagesFromMailBoxOld(Message::MAILBOX_NATIONAL + $nationID, MessageType::diplomacy, $reqTo, 15));
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Message;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Json;
|
||||
use sammo\Message;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
use function sammo\checkSecretPermission;
|
||||
|
||||
class GetRecentMessage extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('integer', 'sequence');
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
$this->args['sequence'] = (int)($this->args['sequence'] ?? -1);
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
private function delayFrequentCall(Session $session): void
|
||||
{
|
||||
$lastMsgGet = Json::decode($session->lastMsgGet) ?? [];
|
||||
$now = new \DateTimeImmutable();
|
||||
$delayTime = false;
|
||||
|
||||
if (count($lastMsgGet) >= 10) {
|
||||
try {
|
||||
if (!is_string($lastMsgGet[0])) {
|
||||
throw new \Exception('Why not string?');
|
||||
}
|
||||
$first = new \DateTimeImmutable($lastMsgGet[0]);
|
||||
$diffSec = TimeUtil::DateIntervalToSeconds($first->diff($now));
|
||||
if ($diffSec < 1) {
|
||||
$delayTime = true;
|
||||
}
|
||||
array_shift($lastMsgGet);
|
||||
} catch (\Exception $e) {
|
||||
$lastMsgGet = [];
|
||||
}
|
||||
}
|
||||
$lastMsgGet[] = TimeUtil::format($now, true);
|
||||
$session->lastMsgGet = Json::encode($lastMsgGet);
|
||||
|
||||
if ($delayTime) {
|
||||
usleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$this->delayFrequentCall($session);
|
||||
$session->setReadOnly();
|
||||
$userID = $session->getUserID();
|
||||
|
||||
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
if ($me === null) {
|
||||
return '장수가 사망했습니다.';
|
||||
}
|
||||
|
||||
[$generalID, $nationID, $generalName] = [$me['no'], $me['nation'], $me['name']];
|
||||
$permission = checkSecretPermission($me, false);
|
||||
$reqSequence = $this->args['sequence'];
|
||||
|
||||
$result = [];
|
||||
$result['result'] = true;
|
||||
$result['keepRecent'] = false;
|
||||
$nextSequence = $reqSequence;
|
||||
$minSequence = $reqSequence;
|
||||
$lastType = null;
|
||||
|
||||
$result['private'] = array_map(function (Message $msg) use (&$nextSequence, &$minSequence, &$lastType) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if ($msg->id <= $minSequence) {
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'private';
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBox($generalID, MessageType::private, 15, $reqSequence));
|
||||
|
||||
$result['public'] = array_map(function (Message $msg) use (&$nextSequence, &$minSequence, &$lastType) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if ($msg->id <= $minSequence) {
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'public';
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBox(Message::MAILBOX_PUBLIC, MessageType::public, 15, $reqSequence));
|
||||
|
||||
$result['national'] = array_map(function (Message $msg) use (&$nextSequence, &$minSequence, &$lastType) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if ($msg->id <= $minSequence) {
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'national';
|
||||
}
|
||||
return $msg->toArray();
|
||||
}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, MessageType::national, 15, $reqSequence));
|
||||
|
||||
$result['diplomacy'] = array_map(function (Message $msg) use (&$nextSequence, &$minSequence, &$lastType, $permission) {
|
||||
if ($msg->id > $nextSequence) {
|
||||
$nextSequence = $msg->id;
|
||||
}
|
||||
if ($msg->id <= $minSequence) {
|
||||
$minSequence = $msg->id;
|
||||
$lastType = 'diplomacy';
|
||||
}
|
||||
$values = $msg->toArray();
|
||||
if ($msg->dest->nationID != 0 && $permission < 3) {
|
||||
$values['text'] = '(외교 메시지입니다)'; //TODO: 외교서신이라 읽을 수 없음을 보여줘야함
|
||||
$values['option']['invalid'] = true;
|
||||
}
|
||||
return $values;
|
||||
}, Message::getMessagesFromMailBox(Message::MAILBOX_NATIONAL + $nationID, MessageType::diplomacy, 15, $reqSequence));
|
||||
|
||||
if ($lastType !== null) {
|
||||
array_pop($result[$lastType]);
|
||||
$result['keepRecent'] = true;
|
||||
} else if ($reqSequence <= 0) {
|
||||
$result['keepRecent'] = true;
|
||||
}
|
||||
|
||||
$result['sequence'] = $nextSequence;
|
||||
$result['nationID'] = $nationID;
|
||||
$result['generalName'] = $generalName;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Message;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Message;
|
||||
use sammo\MessageTarget;
|
||||
use sammo\Validator;
|
||||
|
||||
use function sammo\checkLimit;
|
||||
use function sammo\checkSecretPermission;
|
||||
use function sammo\getBlockLevel;
|
||||
use function sammo\GetImageURL;
|
||||
use function sammo\getNationStaticInfo;
|
||||
use function sammo\increaseRefresh;
|
||||
|
||||
class SendMessage extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v->rule('required', ['mailbox', 'text']);
|
||||
$v->rule('integer', 'mailbox');
|
||||
$v->rule('lengthMin', 'text', 1);
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
$this->args['mailbox'] = (int)($this->args['mailbox'] ?? Message::MAILBOX_PUBLIC);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return static::REQ_GAME_LOGIN;
|
||||
}
|
||||
|
||||
private function genPublicMessage(MessageTarget $src, string $text): Message
|
||||
{
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$msg = new Message(
|
||||
MessageType::public,
|
||||
$src,
|
||||
$src,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
private function genNationalMessage(MessageTarget $src, string $text): Message
|
||||
{
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$dest = new MessageTarget(0, '', $src->nationID, $src->nationName, $src->color);
|
||||
|
||||
$msg = new Message(
|
||||
MessageType::national,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
private function genDiplomacyMessage(MessageTarget $src, int $destNationID, string $text): Message|string
|
||||
{
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$destNation = getNationStaticInfo($destNationID);
|
||||
|
||||
if ($destNation === null) {
|
||||
return '존재하지 않는 국가입니다.';
|
||||
}
|
||||
|
||||
$dest = new MessageTarget(0, '', $destNation['nation'], $destNation['name'], $destNation['color']);
|
||||
|
||||
$msg = new Message(
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
return $msg;
|
||||
}
|
||||
|
||||
private function genPrivateMessage(MessageTarget $src, int $destGeneralID, int $permission, string $text): Message|string
|
||||
{
|
||||
$now = new \DateTime();
|
||||
$unlimited = new \DateTime('9999-12-31');
|
||||
|
||||
$db = DB::db();
|
||||
$destUser = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,permission,penalty FROM general WHERE `no`=%i', $destGeneralID);
|
||||
|
||||
if (!$destUser) {
|
||||
return '존재하지 않는 유저입니다.';
|
||||
}
|
||||
|
||||
$destPermission = checkSecretPermission($destUser, false);
|
||||
if ($permission == 4 && $destPermission == 4 && $destUser['nation'] != $src->nationID) {
|
||||
return '외교권자끼리는 메시지를 보낼 수 없습니다.';
|
||||
}
|
||||
|
||||
$destNation = getNationStaticInfo($destUser['nation']);
|
||||
if ($destNation === null) {
|
||||
$destNation = getNationStaticInfo(0);
|
||||
}
|
||||
|
||||
$dest = new MessageTarget(
|
||||
$destUser['no'],
|
||||
$destUser['name'],
|
||||
$destNation['nation'],
|
||||
$destNation['name'],
|
||||
$destNation['color'],
|
||||
GetImageURL($destUser['imgsvr'], $destUser['picture'])
|
||||
);
|
||||
|
||||
$msg = new Message(
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
$now,
|
||||
$unlimited,
|
||||
[]
|
||||
);
|
||||
|
||||
return $msg;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$userID = $session->userID;
|
||||
$mailbox = $this->args['mailbox'];
|
||||
$text = $this->args['text'];
|
||||
|
||||
increaseRefresh('서신전달', 1);
|
||||
|
||||
$blockLevel = getBlockLevel();
|
||||
if ($blockLevel == 1 || $blockLevel == 3) {
|
||||
return '차단되었습니다.';
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,`name`,`nation`,`officer_level`,`con`,`picture`,`imgsvr`,penalty,permission,belong FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
if (!$me) {
|
||||
$session->logoutGame();
|
||||
return '장수가 없습니다.';
|
||||
}
|
||||
|
||||
$con = checkLimit($me['con']);
|
||||
if ($con >= 2) {
|
||||
return '접속 제한입니다.';
|
||||
}
|
||||
|
||||
$nationID = $me['nation'];
|
||||
$iconPath = GetImageURL($me['imgsvr'], $me['picture']);
|
||||
$srcNation = getNationStaticInfo($me['nation']);
|
||||
|
||||
if ($srcNation === null) {
|
||||
return '존재하지 않는 국가입니다.';
|
||||
}
|
||||
|
||||
$src = new MessageTarget($me['no'], $me['name'], $srcNation['nation'], $srcNation['name'], $srcNation['color'], $iconPath);
|
||||
|
||||
// 전체 메세지
|
||||
if ($mailbox === Message::MAILBOX_PUBLIC) {
|
||||
$msgID = $this->genPublicMessage($src, $text)->send();
|
||||
return [
|
||||
'msgID' => $msgID
|
||||
];
|
||||
}
|
||||
|
||||
$permission = checkSecretPermission($me);
|
||||
|
||||
if ($mailbox >= Message::MAILBOX_NATIONAL) {
|
||||
if ($permission < 4) {
|
||||
$destNationID = $nationID;
|
||||
} else {
|
||||
$destNationID = $mailbox - Message::MAILBOX_NATIONAL;
|
||||
}
|
||||
|
||||
if ($destNationID === $nationID) {
|
||||
$msgID = $this->genNationalMessage($src, $text)->send();
|
||||
return [
|
||||
'msgID' => $msgID
|
||||
];
|
||||
}
|
||||
|
||||
$msgObjOrError = $this->genDiplomacyMessage($src, $destNationID, $text);
|
||||
if(is_string($msgObjOrError)) {
|
||||
return $msgObjOrError;
|
||||
}
|
||||
$msgID = $msgObjOrError->send();
|
||||
return [
|
||||
'msgID' => $msgID
|
||||
];
|
||||
}
|
||||
|
||||
if ($mailbox > 0) {
|
||||
$now = new \DateTime();
|
||||
$lastMsg = new \DateTime($session->lastMsg ?? '0000-00-00');
|
||||
$msg_interval = $now->getTimestamp() - $lastMsg->getTimestamp();
|
||||
if ($msg_interval < 2) {
|
||||
return '개인메세지는 2초당 1건만 보낼 수 있습니다!';
|
||||
}
|
||||
$session->lastMsg = $now->format('Y-m-d H:i:s');
|
||||
|
||||
$msgObjOrError = $this->genPrivateMessage($src, $mailbox, $permission, $text);
|
||||
if(is_string($msgObjOrError)) {
|
||||
return $msgObjOrError;
|
||||
}
|
||||
$msgID = $msgObjOrError->send();
|
||||
|
||||
return [
|
||||
'msgID' => $msgID
|
||||
];
|
||||
}
|
||||
|
||||
return '알 수 없는 에러입니다.';
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ class GetGeneralLog extends \sammo\BaseAPI
|
||||
if (
|
||||
$reqType === self::GENERAL_ACTION &&
|
||||
$testGeneralNPCType < 2 &&
|
||||
$generalID !== $me['generalID'] &&
|
||||
$generalID !== $me['no'] &&
|
||||
$permission < 2
|
||||
) {
|
||||
return '권한이 부족합니다. 유저 장수의 개인 기록은 수뇌만 열람 가능합니다.';
|
||||
|
||||
@@ -6,6 +6,7 @@ use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\DB;
|
||||
use sammo\KVStorage;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Validator;
|
||||
use sammo\WebUtil;
|
||||
|
||||
@@ -36,7 +37,7 @@ class SetNotice extends \sammo\BaseAPI
|
||||
$msg = $this->args['msg'];
|
||||
$userID = $session->userID;
|
||||
$db = DB::db();
|
||||
$me = $db->queryFirstRow('SELECT `no`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
$me = $db->queryFirstRow('SELECT `no`,`name`,nation,`officer_level`,permission,penalty FROM general WHERE `owner`=%i', $userID);
|
||||
|
||||
$permission = checkSecretPermission($me, false);
|
||||
if($permission < 0){
|
||||
@@ -49,7 +50,12 @@ class SetNotice extends \sammo\BaseAPI
|
||||
$nationID = $me['nation'];
|
||||
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationStor->notice = WebUtil::htmlPurify($msg);
|
||||
$nationStor->nationNotice = [
|
||||
'date'=>TimeUtil::now(),
|
||||
'msg'=>WebUtil::htmlPurify($msg),
|
||||
'author'=>$me['name'],
|
||||
'authorID'=>$me['no'],
|
||||
];
|
||||
|
||||
return [
|
||||
'result' => true
|
||||
|
||||
@@ -5,8 +5,8 @@ use \sammo\General;
|
||||
|
||||
class che_계략_향낭 extends \sammo\BaseItem{
|
||||
|
||||
protected $rawName = '항냥';
|
||||
protected $name = '항냥(계략)';
|
||||
protected $rawName = '향낭';
|
||||
protected $name = '향낭(계략)';
|
||||
protected $info = '[계략] 화계·탈취·파괴·선동 : 성공률 +50%p';
|
||||
protected $cost = 3000;
|
||||
protected $consumable = true;
|
||||
|
||||
@@ -10,7 +10,7 @@ class che_명마_12_옥란백용구 extends \sammo\BaseStatItem{
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->info .= "<br>[전투] 남은 병력이 적을수록 회피 확률 증가. 최대 +30%p";
|
||||
$this->info .= "<br>[전투] 남은 병력이 적을수록 회피 확률 증가. 최대 +50%p";
|
||||
}
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux = null)
|
||||
@@ -20,7 +20,7 @@ class che_명마_12_옥란백용구 extends \sammo\BaseStatItem{
|
||||
$leadership = $general->getLeadership(true, true, true, false);
|
||||
$crewL = $general->getVar('crew') / 100;
|
||||
|
||||
return $value + \sammo\Util::valueFit((1 - $crewL / $leadership) * 0.3, 0, 0.3);
|
||||
return $value + \sammo\Util::valueFit((1 - $crewL / $leadership) * 0.5, 0, 0.5);
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ class che_징병_낙주 extends \sammo\BaseItem{
|
||||
|
||||
protected $rawName = '낙주';
|
||||
protected $name = '낙주(징병)';
|
||||
protected $info = '[군사] 징·모병비 -30%, 통솔 순수 능력치 보정 +15%';
|
||||
protected $info = '[군사] 징·모병비 -30%<br>[기타] 통솔 순수 능력치 보정 +15%, 징병/모병/소집해제 시 인구 변동 없음';
|
||||
protected $cost = 200;
|
||||
protected $consumable = false;
|
||||
|
||||
@@ -18,6 +18,10 @@ class che_징병_낙주 extends \sammo\BaseItem{
|
||||
if($varType == 'cost') return $value * 0.7;
|
||||
}
|
||||
|
||||
if($turnType == '징집인구' && $varType == 'score'){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class event_전투특기_징병 extends \sammo\BaseItem{
|
||||
|
||||
protected $rawName = '비급';
|
||||
protected $name = '비급(징병)';
|
||||
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +25%';
|
||||
protected $info = '[군사] 징병/모병 시 훈사 70/84 제공<br>[기타] 통솔 순수 능력치 보정 +25%, 징병/모병/소집해제 시 인구 변동 없음';
|
||||
protected $cost = 100;
|
||||
protected $buyable = true;
|
||||
protected $consumable = false;
|
||||
@@ -17,7 +17,18 @@ class event_전투특기_징병 extends \sammo\BaseItem{
|
||||
|
||||
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
|
||||
if(in_array($turnType, ['징병', '모병'])){
|
||||
if($varType == 'cost') return $value * 0.5;
|
||||
if($varType == 'train' || $varType == 'atmos'){
|
||||
if($turnType === '징병'){
|
||||
return 70;
|
||||
}
|
||||
else{
|
||||
return 84;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($turnType == '징집인구' && $varType == 'score'){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -11,7 +11,7 @@ class event_전투특기_필살 extends \sammo\BaseItem{
|
||||
|
||||
protected $rawName = '비급';
|
||||
protected $name = '비급(필살)';
|
||||
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 항상 최대';
|
||||
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 향상';
|
||||
protected $cost = 100;
|
||||
protected $buyable = true;
|
||||
protected $consumable = false;
|
||||
@@ -22,8 +22,8 @@ class event_전투특기_필살 extends \sammo\BaseItem{
|
||||
return $value + 0.3;
|
||||
}
|
||||
if($statName === 'criticalDamageRange'){
|
||||
[, $rangeMax] = $value;
|
||||
return [$rangeMax, $rangeMax];
|
||||
[$rangeMin, $rangeMax] = $value;
|
||||
return [($rangeMin + $rangeMax) / 2, $rangeMax];
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -9,7 +9,7 @@ class che_event_징병 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 72;
|
||||
protected $name = '징병';
|
||||
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +25%';
|
||||
protected $info = '[군사] 징병/모병 시 훈사 70/84 제공<br>[기타] 통솔 순수 능력치 보정 +25%, 징병/모병/소집해제 시 인구 변동 없음';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -21,9 +21,20 @@ class che_event_징병 extends \sammo\BaseSpecial{
|
||||
|
||||
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
|
||||
if(in_array($turnType, ['징병', '모병'])){
|
||||
if($varType == 'cost') return $value * 0.5;
|
||||
if($varType == 'train' || $varType == 'atmos'){
|
||||
if($turnType === '징병'){
|
||||
return 70;
|
||||
}
|
||||
else{
|
||||
return 84;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($turnType == '징집인구' && $varType == 'score'){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ class che_event_필살 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 71;
|
||||
protected $name = '필살';
|
||||
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 항상 최대';
|
||||
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 향상';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -26,10 +26,10 @@ class che_event_필살 extends \sammo\BaseSpecial{
|
||||
return $value + 0.30;
|
||||
}
|
||||
if($statName === 'criticalDamageRange'){
|
||||
[, $rangeMax] = $value;
|
||||
return [$rangeMax, $rangeMax];
|
||||
[$rangeMin, $rangeMax] = $value;
|
||||
return [($rangeMin + $rangeMax) / 2, $rangeMax];
|
||||
}
|
||||
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ class che_징병 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 72;
|
||||
protected $name = '징병';
|
||||
protected $info = '[군사] 징·모병비 -50%, 통솔 순수 능력치 보정 +25%';
|
||||
protected $info = '[군사] 징병/모병 시 훈사 70/84 제공<br>[기타] 통솔 순수 능력치 보정 +25%, 징병/모병/소집해제 시 인구 변동 없음';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -21,9 +21,20 @@ class che_징병 extends \sammo\BaseSpecial{
|
||||
|
||||
public function onCalcDomestic(string $turnType, string $varType, float $value, $aux=null):float{
|
||||
if(in_array($turnType, ['징병', '모병'])){
|
||||
if($varType == 'cost') return $value * 0.5;
|
||||
if($varType == 'train' || $varType == 'atmos'){
|
||||
if($turnType === '징병'){
|
||||
return 70;
|
||||
}
|
||||
else{
|
||||
return 84;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($turnType == '징집인구' && $varType == 'score'){
|
||||
return 0;
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class che_필살 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 71;
|
||||
protected $name = '필살';
|
||||
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 항상 최대';
|
||||
protected $info = '[전투] 필살 확률 +30%p, 필살 발동시 대상 회피 불가, 필살 계수 향상';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -29,8 +29,8 @@ class che_필살 extends \sammo\BaseSpecial{
|
||||
return $value + 0.30;
|
||||
}
|
||||
if($statName === 'criticalDamageRange'){
|
||||
[, $rangeMax] = $value;
|
||||
return [$rangeMax, $rangeMax];
|
||||
[$rangeMin, $rangeMax] = $value;
|
||||
return [($rangeMin + $rangeMax) / 2, $rangeMax];
|
||||
}
|
||||
|
||||
return $value;
|
||||
|
||||
@@ -10,6 +10,7 @@ use sammo\DTO\AuctionBidItemData;
|
||||
use sammo\DTO\AuctionInfo;
|
||||
use sammo\Enums\AuctionType;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Enums\RankColumn;
|
||||
use sammo\Enums\ResourceType;
|
||||
|
||||
@@ -22,7 +23,7 @@ abstract class Auction
|
||||
|
||||
public const COEFF_AUCTION_CLOSE_MINUTES = 24;
|
||||
public const COEFF_EXTENSION_MINUTES_PER_BID = (1 / 6);
|
||||
public const COEFF_EXTENSION_MINUTES_LIMIT_BY_BID = 1;
|
||||
public const COEFF_EXTENSION_MINUTES_LIMIT_BY_BID = 0.5;
|
||||
public const COEFF_EXTENSION_MINUTES_BY_EXTENSION_QUERY = 1;
|
||||
public const MIN_AUCTION_CLOSE_MINUTES = 30;
|
||||
public const MIN_EXTENSION_MINUTES_PER_BID = 1;
|
||||
@@ -40,6 +41,7 @@ abstract class Auction
|
||||
if ($namePool === null) {
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'obfuscatedNamePool',
|
||||
)));
|
||||
$namePool = [];
|
||||
foreach (GameConst::$randGenFirstName as $ch0) {
|
||||
@@ -244,7 +246,7 @@ abstract class Auction
|
||||
//TODO: 전역 알림이 나타나야한다. 일반 메시지보다는 중요하고, 메시지보단 약하게..
|
||||
//TODO: 바로가기를 제공하는 편이 좋을 것 같다.
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PRIVATE,
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
$reason,
|
||||
@@ -281,6 +283,9 @@ abstract class Auction
|
||||
$general = $this->general;
|
||||
|
||||
$highestBid = $this->getHighestBid();
|
||||
if ($highestBid !== null && $amount < $highestBid->amount * 1.01) {
|
||||
return '현재입찰가보다 1% 높게 입찰해야 합니다.';
|
||||
}
|
||||
if ($highestBid !== null && $amount < $highestBid->amount + 10) {
|
||||
return '현재입찰가보다 10 포인트 높게 입찰해야 합니다.';
|
||||
}
|
||||
@@ -505,7 +510,7 @@ abstract class Auction
|
||||
//TODO: 전역 알림이 나타나야한다. 일반 메시지보다는 중요하고, 메시지보단 약하게..
|
||||
//TODO: 바로가기를 제공하는 편이 좋을 것 같다.
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PRIVATE,
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
$failReason,
|
||||
|
||||
@@ -7,6 +7,7 @@ use sammo\DTO\AuctionBidItem;
|
||||
use sammo\DTO\AuctionInfo;
|
||||
use sammo\DTO\AuctionInfoDetail;
|
||||
use sammo\Enums\AuctionType;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Enums\ResourceType;
|
||||
|
||||
abstract class AuctionBasicResource extends Auction
|
||||
@@ -145,7 +146,7 @@ abstract class AuctionBasicResource extends Auction
|
||||
//TODO: 전역 알림이 나타나야한다. 일반 메시지보다는 중요하고, 메시지보단 약하게..
|
||||
//TODO: 바로가기를 제공하는 편이 좋을 것 같다.
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PRIVATE,
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
"{$this->auctionID}번 {$hostResName} 경매에 입찰이 없어 취소되었습니다.",
|
||||
|
||||
@@ -110,7 +110,11 @@ class AuctionUniqueItem extends Auction
|
||||
}
|
||||
$auction = new static($auctionID, $general);
|
||||
try {
|
||||
$auction->bid($startAmount, false);
|
||||
$failReason = $auction->bid($startAmount, false);
|
||||
if($failReason){
|
||||
$auction->closeAuction();
|
||||
return "경매를 시작했지만, 첫 입찰에 실패했습니다: {$failReason}";
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
//실패해선 안된다.
|
||||
$msg = $e->getMessage();
|
||||
|
||||
@@ -179,6 +179,15 @@ class che_등용수락 extends Command\GeneralCommand{
|
||||
$db->update('nation', $setScoutNationValues, 'nation=%i', $destNationID);
|
||||
|
||||
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
|
||||
if($general->getNPCType() < 2){
|
||||
$general->setAuxVar(
|
||||
InheritanceKey::max_belong->value,
|
||||
max(
|
||||
$general->getVar('belong'),
|
||||
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
|
||||
)
|
||||
);
|
||||
}
|
||||
$general->setVar('permission', 'normal');
|
||||
$general->setVar('belong', 1);
|
||||
$general->setVar('officer_level', 1);
|
||||
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\Command\General;
|
||||
|
||||
use \sammo\DB;
|
||||
use \sammo\Util;
|
||||
use \sammo\JosaUtil;
|
||||
use \sammo\General;
|
||||
use \sammo\ActionLogger;
|
||||
use \sammo\GameConst;
|
||||
use \sammo\GameUnitConst;
|
||||
use \sammo\LastTurn;
|
||||
use \sammo\Command;
|
||||
use \sammo\Json;
|
||||
|
||||
use function \sammo\tryUniqueItemLottery;
|
||||
use function \sammo\getAllNationStaticInfo;
|
||||
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
|
||||
use function sammo\buildNationTypeClass;
|
||||
use function sammo\genGenericUniqueRNGFromGeneral;
|
||||
use function sammo\refreshNationStaticInfo;
|
||||
use function sammo\GetNationColors;
|
||||
|
||||
|
||||
class che_무작위건국 extends Command\GeneralCommand
|
||||
{
|
||||
static protected $actionName = '무작위 도시 건국';
|
||||
static public $reqArg = true;
|
||||
|
||||
protected function argTest(): bool
|
||||
{
|
||||
if ($this->arg === null) {
|
||||
return false;
|
||||
}
|
||||
$nationName = $this->arg['nationName'] ?? null;
|
||||
$nationType = $this->arg['nationType'] ?? null;
|
||||
$colorType = $this->arg['colorType'] ?? null;
|
||||
|
||||
if ($nationName === null || $nationType === null || $colorType === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!is_string($nationName) || !is_string($nationType) || !is_int($colorType)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mb_strwidth($nationName) > 18 || $nationName == '') {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!key_exists($colorType, GetNationColors())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
$nationTypeClass = buildNationTypeClass($nationType);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->arg = [
|
||||
'nationName' => $nationName,
|
||||
'nationType' => $nationType,
|
||||
'colorType' => $colorType
|
||||
];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$env = $this->env;
|
||||
|
||||
$this->setNation(['gennum', 'aux']);
|
||||
|
||||
$relYear = $env['year'] - $env['startyear'];
|
||||
|
||||
$this->minConditionConstraints = [
|
||||
ConstraintHelper::BeOpeningPart($relYear + 1),
|
||||
ConstraintHelper::ReqNationValue('level', '국가규모', '==', 0, '정식 국가가 아니어야합니다.')
|
||||
];
|
||||
}
|
||||
|
||||
protected function initWithArg()
|
||||
{
|
||||
$env = $this->env;
|
||||
$relYear = $env['year'] - $env['startyear'];
|
||||
|
||||
$nationName = $this->arg['nationName'];
|
||||
$nationType = $this->arg['nationType'];
|
||||
$colorType = $this->arg['colorType'];
|
||||
|
||||
$this->fullConditionConstraints = [
|
||||
ConstraintHelper::BeLord(),
|
||||
ConstraintHelper::WanderingNation(),
|
||||
ConstraintHelper::ReqNationValue('gennum', '수하 장수', '>=', 2),
|
||||
ConstraintHelper::BeOpeningPart($relYear + 1),
|
||||
ConstraintHelper::CheckNationNameDuplicate($nationName),
|
||||
ConstraintHelper::AllowJoinAction(),
|
||||
];
|
||||
}
|
||||
|
||||
public function getBrief(): string
|
||||
{
|
||||
$nationName = $this->arg['nationName'];
|
||||
$josaUl = JosaUtil::pick($nationName, '을');
|
||||
return "【{$nationName}】{$josaUl} 무작위 도시에 건국";
|
||||
}
|
||||
|
||||
public function getCost(): array
|
||||
{
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
public function getPreReqTurn(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function getPostReqTurn(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function run(\Sammo\RandUtil $rng): bool
|
||||
{
|
||||
if (!$this->hasFullConditionMet()) {
|
||||
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$env = $this->env;
|
||||
|
||||
$general = $this->generalObj;
|
||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||
$generalName = $general->getName();
|
||||
$logger = $general->getLogger();
|
||||
|
||||
$initYearMonth = Util::joinYearMonth($env['init_year'], $env['init_month']);
|
||||
$yearMonth = Util::joinYearMonth($env['year'], $env['month']);
|
||||
if($yearMonth <= $initYearMonth){
|
||||
$logger->pushGeneralActionLog("다음 턴부터 건국할 수 있습니다. <1>$date</>");
|
||||
$this->alternative = new che_인재탐색($general, $this->env, null);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$cities = $db->queryFirstColumn('SELECT city FROM city where `level`>=5 and `level`<=6 and nation=0');
|
||||
if(!$cities){
|
||||
$logger->pushGeneralActionLog("건국할 수 있는 도시가 없습니다. <1>$date</>");
|
||||
$this->alternative = new che_해산($general, $this->env, null);
|
||||
return false;
|
||||
}
|
||||
$cityID = $rng->choice($cities);
|
||||
if($general->getCityID() == $cityID){
|
||||
$this->setCity();
|
||||
}
|
||||
else{
|
||||
$this->generalObj->setVar('city', $cityID);
|
||||
$this->setCity();
|
||||
$db->update('general', [
|
||||
'city' => $cityID
|
||||
], 'nation = %i', $general->getNationID());
|
||||
}
|
||||
|
||||
$josaYi = JosaUtil::pick($generalName, '이');
|
||||
|
||||
$nationName = $this->arg['nationName'];
|
||||
$nationType = $this->arg['nationType'];
|
||||
$colorType = GetNationColors()[$this->arg['colorType']];
|
||||
|
||||
$cityName = $this->city['name'];
|
||||
|
||||
$josaUl = JosaUtil::pick($nationName, '을');
|
||||
|
||||
$nationTypeClass = buildNationTypeClass($nationType);
|
||||
$nationTypeName = $nationTypeClass->getName();
|
||||
|
||||
$logger->pushGeneralActionLog("<D><b>{$nationName}</b></>{$josaUl} 건국하였습니다. <1>$date</>");
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <G><b>{$cityName}</b></>에 국가를 건설하였습니다.");
|
||||
|
||||
$josaNationYi = JosaUtil::pick($nationName, '이');
|
||||
$logger->pushGlobalHistoryLog("<Y><b>【건국】</b></>{$nationTypeName} <D><b>{$nationName}</b></>{$josaNationYi} 새로이 등장하였습니다.");
|
||||
$logger->pushGeneralHistoryLog("<D><b>{$nationName}</b></>{$josaUl} 건국");
|
||||
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <D><b>{$nationName}</b></>{$josaUl} 건국");
|
||||
|
||||
$exp = 1000;
|
||||
$ded = 1000;
|
||||
|
||||
$general->addExperience($exp);
|
||||
$general->addDedication($ded);
|
||||
|
||||
$aux = Json::decode($this->nation['aux']) ?? [];
|
||||
$aux['can_국기변경'] = 1;
|
||||
$aux['can_무작위수도이전'] = 1;
|
||||
|
||||
$db->update('city', [
|
||||
'nation' => $general->getNationID(),
|
||||
'conflict' => '{}'
|
||||
], 'city=%i', $general->getCityID());
|
||||
|
||||
$db->update('nation', [
|
||||
'name' => $nationName,
|
||||
'color' => $colorType,
|
||||
'level' => 1,
|
||||
'type' => $nationType,
|
||||
'capital' => $general->getCityID(),
|
||||
'aux' => Json::encode($aux)
|
||||
], 'nation=%i', $general->getNationID());
|
||||
|
||||
refreshNationStaticInfo();
|
||||
|
||||
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
|
||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||
$general->checkStatChange();
|
||||
tryUniqueItemLottery(genGenericUniqueRNGFromGeneral($general), $general, '건국');
|
||||
$general->applyDB($db);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public function exportJSVars(): array
|
||||
{
|
||||
$nationTypes = [];
|
||||
foreach (GameConst::$availableNationType as $nationType) {
|
||||
$nationClass = buildNationTypeClass($nationType);
|
||||
$nationTypes[$nationType] = [
|
||||
'type' => $nationType,
|
||||
'name' => $nationClass->getName(),
|
||||
'pros' => $nationClass::$pros,
|
||||
'cons' => $nationClass::$cons
|
||||
];
|
||||
}
|
||||
return [
|
||||
'procRes' => [
|
||||
'available건국' => count(getAllNationStaticInfo()) < $this->env['maxnation'],
|
||||
'nationTypes' => $nationTypes,
|
||||
'colors' => GetNationColors(),
|
||||
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -62,8 +62,6 @@ class che_소집해제 extends Command\GeneralCommand{
|
||||
$general = $this->generalObj;
|
||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||
|
||||
$crew = $general->getVar('crew');
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
$logger->pushGeneralActionLog("병사들을 <R>소집해제</>하였습니다. <1>$date</>");
|
||||
@@ -71,8 +69,10 @@ class che_소집해제 extends Command\GeneralCommand{
|
||||
$exp = 70;
|
||||
$ded = 100;
|
||||
|
||||
$crewUp = $general->onCalcDomestic('징집인구', 'score', $general->getVar('crew'));
|
||||
|
||||
$db->update('city', [
|
||||
'pop'=>$db->sqleval('pop + %i', $crew)
|
||||
'pop'=>$db->sqleval('pop + %i', $crewUp)
|
||||
], 'city=%i', $general->getCityID());
|
||||
|
||||
$general->setVar('crew', 0);
|
||||
|
||||
@@ -10,6 +10,7 @@ use \sammo\{
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
|
||||
use function sammo\tryUniqueItemLottery;
|
||||
use function sammo\CheckHall;
|
||||
|
||||
class che_은퇴 extends Command\GeneralCommand{
|
||||
static protected $actionName = '은퇴';
|
||||
@@ -59,12 +60,17 @@ class che_은퇴 extends Command\GeneralCommand{
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
$env = $this->env;
|
||||
|
||||
$general = $this->generalObj;
|
||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
if ($env['isunited'] == 0) {
|
||||
CheckHall($general->getID());
|
||||
}
|
||||
|
||||
$general->rebirth();
|
||||
$logger->pushGeneralActionLog("은퇴하였습니다. <1>$date</>");
|
||||
|
||||
|
||||
@@ -184,10 +184,13 @@ class che_징병 extends Command\GeneralCommand
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
$setTrain = $general->onCalcDomestic(static::$actionName, 'train', static::$defaultTrain);
|
||||
$setAtmos = $general->onCalcDomestic(static::$actionName, 'atmos', static::$defaultAtmos);
|
||||
|
||||
if ($reqCrewType->id == $currCrewType->id && $currCrew > 0) {
|
||||
$logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 추가{$this->getName()}했습니다. <1>$date</>");
|
||||
$train = ($currCrew * $general->getVar('train') + $reqCrew * static::$defaultTrain) / ($currCrew + $reqCrew);
|
||||
$atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * static::$defaultAtmos) / ($currCrew + $reqCrew);
|
||||
$train = ($currCrew * $general->getVar('train') + $reqCrew * $setTrain) / ($currCrew + $reqCrew);
|
||||
$atmos = ($currCrew * $general->getVar('atmos') + $reqCrew * $setAtmos) / ($currCrew + $reqCrew);
|
||||
|
||||
$general->increaseVar('crew', $reqCrew);
|
||||
$general->setVar('train', $train);
|
||||
@@ -196,15 +199,17 @@ class che_징병 extends Command\GeneralCommand
|
||||
$logger->pushGeneralActionLog("{$crewTypeName} <C>{$reqCrewText}</>명을 {$this->getName()}했습니다. <1>$date</>");
|
||||
$general->setVar('crewtype', $reqCrewType->id);
|
||||
$general->setVar('crew', $reqCrew);
|
||||
$general->setVar('train', static::$defaultTrain);
|
||||
$general->setVar('atmos', static::$defaultAtmos);
|
||||
$general->setVar('train', $setTrain);
|
||||
$general->setVar('atmos', $setAtmos);
|
||||
}
|
||||
|
||||
$newTrust = Util::valueFit($this->city['trust'] - ($reqCrew / $this->city['pop']) / static::$costOffset * 100, 0);
|
||||
$reqCrewDown = $general->onCalcDomestic('징집인구', 'score', $reqCrew);
|
||||
|
||||
$newTrust = Util::valueFit($this->city['trust'] - ($reqCrewDown / $this->city['pop']) / static::$costOffset * 100, 0);
|
||||
|
||||
$db->update('city', [
|
||||
'trust' => $newTrust,
|
||||
'pop' => $this->city['pop'] - $reqCrew
|
||||
'pop' => $this->city['pop'] - $reqCrewDown
|
||||
], 'city=%i', $general->getCityID());
|
||||
|
||||
$exp = Util::round($reqCrew / 100);
|
||||
|
||||
@@ -113,6 +113,15 @@ class che_하야 extends Command\GeneralCommand{
|
||||
$general->setVar('troop', 0);
|
||||
|
||||
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
|
||||
if($general->getNPCType() < 2){
|
||||
$general->setAuxVar(
|
||||
InheritanceKey::max_belong->value,
|
||||
max(
|
||||
$general->getVar('belong'),
|
||||
$general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$this->setResultTurn(new LastTurn(static::getName(), $this->arg));
|
||||
$general->checkStatChange();
|
||||
|
||||
@@ -94,6 +94,7 @@ class che_화계 extends Command\GeneralCommand
|
||||
|
||||
$prob = $maxGenScore / GameConst::$sabotageProbCoefByStat;
|
||||
$prob += $probCorrection;
|
||||
$prob += (log(count($destCityGeneralList) + 1, 2) - 1.25) * GameConst::$sabotageDefenceCoefByGeneralCnt;
|
||||
|
||||
$prob += $destCity['secu'] / $destCity['secu_max'] / 5; //최대 20%p
|
||||
$prob += $destCity['supply'] ? 0.1 : 0;
|
||||
|
||||
@@ -19,6 +19,7 @@ use function \sammo\GetImageURL;
|
||||
|
||||
use \sammo\Constraint\Constraint;
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
class che_몰수 extends Command\NationCommand
|
||||
{
|
||||
@@ -186,7 +187,7 @@ class che_몰수 extends Command\NationCommand
|
||||
GetImageURL($destGeneral->getVar('imgsvr'), $destGeneral->getVar('picture'))
|
||||
);
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PUBLIC,
|
||||
MessageType::public,
|
||||
$src,
|
||||
$src,
|
||||
$text,
|
||||
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\Command\Nation;
|
||||
|
||||
use \sammo\DB;
|
||||
use \sammo\Util;
|
||||
use \sammo\JosaUtil;
|
||||
use \sammo\General;
|
||||
use \sammo\DummyGeneral;
|
||||
use \sammo\ActionLogger;
|
||||
use \sammo\GameConst;
|
||||
use \sammo\LastTurn;
|
||||
use \sammo\GameUnitConst;
|
||||
use \sammo\Command;
|
||||
use \sammo\MessageTarget;
|
||||
use \sammo\Message;
|
||||
use \sammo\CityConst;
|
||||
use \sammo\Constraint\Constraint;
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\InheritanceKey;
|
||||
use sammo\Event\Action;
|
||||
use sammo\Json;
|
||||
|
||||
class che_무작위수도이전 extends Command\NationCommand
|
||||
{
|
||||
static protected $actionName = '무작위 수도 이전';
|
||||
|
||||
protected function argTest(): bool
|
||||
{
|
||||
$this->arg = [];
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected function init()
|
||||
{
|
||||
$env = $this->env;
|
||||
$relYear = $env['year'] - $env['startyear'];
|
||||
|
||||
$this->setCity();
|
||||
$this->setNation(['capital', 'aux']);
|
||||
|
||||
$this->fullConditionConstraints = [
|
||||
ConstraintHelper::OccupiedCity(),
|
||||
ConstraintHelper::BeLord(),
|
||||
ConstraintHelper::SuppliedCity(),
|
||||
ConstraintHelper::BeOpeningPart($relYear + 1),
|
||||
ConstraintHelper::ReqNationAuxValue("can_무작위수도이전", 0, '>', 0, '더이상 변경이 불가능합니다.')
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public function getCommandDetailTitle():string{
|
||||
$name = $this->getName();
|
||||
|
||||
$reqTurn = $this->getPreReqTurn()+1;
|
||||
|
||||
return "{$name}/{$reqTurn}턴";
|
||||
}
|
||||
|
||||
|
||||
public function getCost(): array
|
||||
{
|
||||
return [0, 0];
|
||||
}
|
||||
|
||||
public function getPreReqTurn(): int
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
public function getPostReqTurn(): int
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function run(\Sammo\RandUtil $rng): bool
|
||||
{
|
||||
if (!$this->hasFullConditionMet()) {
|
||||
throw new \RuntimeException('불가능한 커맨드를 강제로 실행 시도');
|
||||
}
|
||||
|
||||
$db = DB::db();
|
||||
|
||||
$general = $this->generalObj;
|
||||
$generalID = $general->getID();
|
||||
$generalName = $general->getName();
|
||||
$date = $general->getTurnTime($general::TURNTIME_HM);
|
||||
|
||||
$year = $this->env['year'];
|
||||
$month = $this->env['month'];
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
$oldCityID = $this->nation['capital'];
|
||||
|
||||
$cities = $db->queryFirstColumn('SELECT city FROM city where `level`>=5 and `level`<=6 and nation=0');
|
||||
if (!$cities) {
|
||||
$logger->pushGeneralActionLog("이동할 수 있는 도시가 없습니다. <1>$date</>");
|
||||
return false;
|
||||
}
|
||||
$destCityID = $rng->choice($cities);
|
||||
$this->setDestCity($destCityID, true);
|
||||
|
||||
|
||||
$destCity = $this->destCity;
|
||||
$destCityID = $destCity['city'];
|
||||
$destCityName = $destCity['name'];
|
||||
|
||||
$nationID = $general->getNationID();
|
||||
$nationName = $this->nation['name'];
|
||||
|
||||
$josaRo = JosaUtil::pick($destCityName, '로');
|
||||
|
||||
$general->addExperience(5 * ($this->getPreReqTurn() + 1));
|
||||
$general->addDedication(5 * ($this->getPreReqTurn() + 1));
|
||||
|
||||
$josaYi = JosaUtil::pick($generalName, '이');
|
||||
$josaYiNation = JosaUtil::pick($nationName, '이');
|
||||
|
||||
$aux = Json::decode($this->nation['aux']);
|
||||
$aux["can_무작위수도이전"] -= 1;
|
||||
|
||||
$db->update('city', [
|
||||
'nation' => $nationID,
|
||||
'conflict' => '{}'
|
||||
], 'city=%i', $destCityID);
|
||||
$db->update('nation', [
|
||||
'capital' => $destCityID,
|
||||
'aux'=>Json::encode($aux),
|
||||
], 'nation=%i', $nationID);
|
||||
$db->update('city', [
|
||||
'nation' => 0,
|
||||
'front' => 0,
|
||||
'conflict' => '{}',
|
||||
'officer_set' => 0,
|
||||
], 'city=%i', $oldCityID);
|
||||
|
||||
$general->setVar('city', $destCityID);
|
||||
$generalList = $db->queryFirstColumn('SELECT no FROM general WHERE nation=%i AND no!=%i', $general->getNationID(), $general->getID());
|
||||
if ($generalList) {
|
||||
$db->update('general', [
|
||||
'city' => $destCityID
|
||||
], 'no IN %li', $generalList);
|
||||
}
|
||||
foreach ($generalList as $targetGeneralID) {
|
||||
$targetLogger = new ActionLogger($targetGeneralID, $general->getNationID(), $year, $month);
|
||||
$targetLogger->pushGeneralActionLog("국가 수도를 <G><b>{$destCityName}</b></>{$josaRo} 옮겼습니다.", ActionLogger::PLAIN);
|
||||
$targetLogger->flush();
|
||||
}
|
||||
|
||||
\sammo\refreshNationStaticInfo();
|
||||
|
||||
$general->increaseInheritancePoint(InheritanceKey::active_action, 1);
|
||||
$logger->pushGeneralActionLog("<G><b>{$destCityName}</b></>{$josaRo} 국가를 옮겼습니다. <1>$date</>");
|
||||
$logger->pushGeneralHistoryLog("<G><b>{$destCityName}</b></>{$josaRo} <M>무작위 수도 이전</>");
|
||||
$logger->pushNationalHistoryLog("<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>{$josaRo} <M>무작위 수도 이전</>");
|
||||
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <G><b>{$destCityName}</b></>{$josaRo} <M>수도 이전</>하였습니다.");
|
||||
$logger->pushGlobalHistoryLog("<S><b>【무작위 수도 이전】</b></><D><b>{$nationName}</b></>{$josaYiNation} <G><b>{$destCityName}</b></>{$josaRo} <M>수도 이전</>하였습니다.");
|
||||
|
||||
$this->setResultTurn(new LastTurn($this->getName(), $this->arg, 0));
|
||||
$general->applyDB($db);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ class che_불가침수락 extends Command\NationCommand
|
||||
$month = $this->arg['month'];
|
||||
|
||||
$currentMonth = $env['year'] * 12 + $env['month'] - 1;
|
||||
$reqMonth = $year * 12 + $month - 1;
|
||||
$reqMonth = $year * 12 + $month;
|
||||
|
||||
$nationID = $this->nation['nation'];
|
||||
|
||||
@@ -199,7 +199,7 @@ class che_불가침수락 extends Command\NationCommand
|
||||
$destLogger = $this->destGeneralObj->getLogger();
|
||||
|
||||
$currentMonth = $env['year'] * 12 + $env['month'] - 1;
|
||||
$reqMonth = $year * 12 + $month - 1;
|
||||
$reqMonth = $year * 12 + $month;
|
||||
|
||||
$db->update(
|
||||
'diplomacy',
|
||||
|
||||
@@ -22,6 +22,7 @@ use function \sammo\getNationStaticInfo;
|
||||
|
||||
use \sammo\Constraint\Constraint;
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
class che_불가침제의 extends Command\NationCommand
|
||||
{
|
||||
@@ -202,7 +203,7 @@ class che_불가침제의 extends Command\NationCommand
|
||||
$josaWa = JosaUtil::pick($nationName, '와');
|
||||
|
||||
$msg = new DiplomaticMessage(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
"{$nationName}{$josaWa} {$year}년 {$month}월까지 불가침 제의 서신",
|
||||
|
||||
@@ -20,6 +20,7 @@ use function \sammo\GetImageURL;
|
||||
|
||||
use \sammo\Constraint\Constraint;
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
class che_불가침파기제의 extends Command\NationCommand{
|
||||
static protected $actionName = '불가침 파기 제의';
|
||||
@@ -150,7 +151,7 @@ class che_불가침파기제의 extends Command\NationCommand{
|
||||
$validUntil->add(new \DateInterval("PT{$validMinutes}M"));
|
||||
|
||||
$msg = new DiplomaticMessage(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
"{$nationName}의 불가침 파기 제의 서신",
|
||||
|
||||
@@ -21,6 +21,7 @@ use function \sammo\GetImageURL;
|
||||
|
||||
use \sammo\Constraint\Constraint;
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
class che_선전포고 extends Command\NationCommand
|
||||
{
|
||||
@@ -175,7 +176,7 @@ class che_선전포고 extends Command\NationCommand
|
||||
$destNation['color']
|
||||
);
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_NATIONAL,
|
||||
MessageType::national,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
|
||||
@@ -131,7 +131,7 @@ class che_의병모집 extends Command\NationCommand
|
||||
$gameStor = KVStorage::getStorage($db, 'game_env'); //TODO: 차라리 env가 이거여야..?
|
||||
|
||||
$avgGenCnt = $db->queryFirstField('SELECT avg(gennum) FROM nation WHERE level > 0');
|
||||
$createGenCnt = 5 + Util::round($avgGenCnt / 10);
|
||||
$createGenCnt = 3 + Util::round($avgGenCnt / 8);
|
||||
$createGenIdx = $gameStor->npccount + 1;
|
||||
$lastCreatGenIdx = $createGenIdx + $createGenCnt;
|
||||
|
||||
@@ -156,6 +156,7 @@ class che_의병모집 extends Command\NationCommand
|
||||
$newNPC->setNPCType(4);
|
||||
$newNPC->setMoney(1000, 1000);
|
||||
$newNPC->setSpecYear(19, 19);
|
||||
$newNPC->setExpDed($avgGen['exp'], $avgGen['ded']);
|
||||
$newNPC->fillRemainSpecAsRandom($pickTypeList, $avgGen, $env);
|
||||
|
||||
$newNPC->build($this->env);
|
||||
|
||||
@@ -20,6 +20,7 @@ use function \sammo\GetImageURL;
|
||||
|
||||
use \sammo\Constraint\Constraint;
|
||||
use \sammo\Constraint\ConstraintHelper;
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
class che_종전제의 extends Command\NationCommand{
|
||||
static protected $actionName = '종전 제의';
|
||||
@@ -148,7 +149,7 @@ class che_종전제의 extends Command\NationCommand{
|
||||
$validUntil->add(new \DateInterval("PT{$validMinutes}M"));
|
||||
|
||||
$msg = new DiplomaticMessage(
|
||||
Message::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$src,
|
||||
$dest,
|
||||
"{$nationName}의 종전 제의 서신",
|
||||
|
||||
@@ -171,6 +171,9 @@ class che_초토화 extends Command\NationCommand{
|
||||
'pop'=>$db->sqleval('greatest(pop_max*0.1, pop*0.2)'),
|
||||
'agri'=>$db->sqleval('greatest(agri_max*0.1, agri*0.2)'),
|
||||
'comm'=>$db->sqleval('greatest(comm_max*0.1, comm*0.2)'),
|
||||
'secu'=>$db->sqleval('greatest(secu_max*0.1, secu*0.2)'),
|
||||
'def'=>$db->sqleval('greatest(def_max*0.1, def*0.2)'),
|
||||
'wall'=>$db->sqleval('greatest(wall_max*0.1, wall*0.5)'),
|
||||
'nation'=>0,
|
||||
'front'=>0,
|
||||
'conflict'=>'{}'
|
||||
|
||||
@@ -59,6 +59,9 @@ class che_피장파장 extends Command\NationCommand
|
||||
if (!in_array($commandType, GameConst::$availableChiefCommand['전략'])) {
|
||||
return false;
|
||||
}
|
||||
if($commandType == Util::getClassNameFromObj($this)){
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
$this->arg = [
|
||||
@@ -75,7 +78,7 @@ class che_피장파장 extends Command\NationCommand
|
||||
$env = $this->env;
|
||||
|
||||
$this->setCity();
|
||||
$this->setNation();
|
||||
$this->setNation(['strategic_cmd_limit']);
|
||||
|
||||
$this->minConditionConstraints = [
|
||||
ConstraintHelper::OccupiedCity(),
|
||||
@@ -113,6 +116,7 @@ class che_피장파장 extends Command\NationCommand
|
||||
[0, 1],
|
||||
'선포, 전쟁중인 상대국에게만 가능합니다.'
|
||||
),
|
||||
ConstraintHelper::AvailableStrategicCommand(),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -120,8 +124,9 @@ class che_피장파장 extends Command\NationCommand
|
||||
{
|
||||
$name = $this->getName();
|
||||
$reqTurn = $this->getPreReqTurn() + 1;
|
||||
$postReqTurn = $this->getPostReqTurn();
|
||||
|
||||
return "{$name}/{$reqTurn}턴(대상 재사용 대기 {$this->getTargetPostReqTurn()})";
|
||||
return "{$name}/{$reqTurn}턴(재사용 대기 $postReqTurn, 대상 재사용 대기 {$this->getTargetPostReqTurn()})";
|
||||
}
|
||||
|
||||
public function getCost(): array
|
||||
@@ -136,7 +141,7 @@ class che_피장파장 extends Command\NationCommand
|
||||
|
||||
public function getPostReqTurn(): int
|
||||
{
|
||||
return 0;
|
||||
return 8;
|
||||
}
|
||||
|
||||
public function getTargetPostReqTurn(): int
|
||||
@@ -251,7 +256,13 @@ class che_피장파장 extends Command\NationCommand
|
||||
|
||||
$oneAvailableCommandName = null;
|
||||
|
||||
$thisClassName = Util::getClassNameFromObj($this);
|
||||
|
||||
foreach (GameConst::$availableChiefCommand['전략'] as $commandType) {
|
||||
if($commandType == $thisClassName){
|
||||
continue;
|
||||
}
|
||||
|
||||
$cmd = buildNationCommandClass($commandType, $generalObj, $this->env, new LastTurn());
|
||||
$cmdName = $cmd->getName();
|
||||
$remainTurn = 0;
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\Convert;
|
||||
use sammo\DTO\Attr\JsonString;
|
||||
use sammo\DTO\Attr\NullIsUndefined;
|
||||
use sammo\DTO\Attr\RawName;
|
||||
use sammo\DTO\Converter\DateTimeConverter;
|
||||
use LDTO\Attr\Convert;
|
||||
use LDTO\Attr\JsonString;
|
||||
use LDTO\Attr\NullIsUndefined;
|
||||
use LDTO\Attr\RawName;
|
||||
use LDTO\Converter\DateTimeConverter;
|
||||
|
||||
class AuctionBidItem extends DTO
|
||||
class AuctionBidItem extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
#[NullIsUndefined]
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\NullIsUndefined;
|
||||
use LDTO\Attr\NullIsUndefined;
|
||||
|
||||
class AuctionBidItemData extends DTO
|
||||
class AuctionBidItemData extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
#[NullIsUndefined]
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\Convert;
|
||||
use sammo\DTO\Attr\JsonString;
|
||||
use sammo\DTO\Attr\NullIsUndefined;
|
||||
use sammo\DTO\Attr\RawName;
|
||||
use sammo\DTO\Converter\DateTimeConverter;
|
||||
use LDTO\Attr\Convert;
|
||||
use LDTO\Attr\JsonString;
|
||||
use LDTO\Attr\NullIsUndefined;
|
||||
use LDTO\Attr\RawName;
|
||||
use LDTO\Converter\DateTimeConverter;
|
||||
use sammo\Enums\AuctionType;
|
||||
use sammo\Enums\ResourceType;
|
||||
|
||||
class AuctionInfo extends DTO
|
||||
class AuctionInfo extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
#[NullIsUndefined]
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\Convert;
|
||||
use sammo\DTO\Attr\NullIsUndefined;
|
||||
use sammo\DTO\Converter\DateTimeConverter;
|
||||
use LDTO\Attr\Convert;
|
||||
use LDTO\Attr\NullIsUndefined;
|
||||
use LDTO\Converter\DateTimeConverter;
|
||||
|
||||
class AuctionInfoDetail extends DTO
|
||||
class AuctionInfoDetail extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
public string $title,
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\Convert;
|
||||
use sammo\DTO\Converter\MapConverter;
|
||||
use LDTO\Attr\Convert;
|
||||
use LDTO\Converter\MapConverter;
|
||||
use sammo\DTO\SelectItem;
|
||||
|
||||
//https://json2dto.atymic.dev/
|
||||
|
||||
class BettingInfo extends DTO
|
||||
class BettingInfo extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
public int $id,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\NullIsUndefined;
|
||||
use sammo\DTO\Attr\RawName;
|
||||
use LDTO\Attr\NullIsUndefined;
|
||||
use LDTO\Attr\RawName;
|
||||
|
||||
class BettingItem extends DTO
|
||||
class BettingItem extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
#[RawName('id')]
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\Convert;
|
||||
use sammo\DTO\Converter\MapConverter;
|
||||
use LDTO\Attr\Convert;
|
||||
use LDTO\Converter\MapConverter;
|
||||
|
||||
class SelectItem extends DTO
|
||||
class SelectItem extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
public string $title,
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
use sammo\DTO\Attr\NullIsUndefined;
|
||||
use sammo\DTO\Attr\RawName;
|
||||
use LDTO\Attr\NullIsUndefined;
|
||||
use LDTO\Attr\RawName;
|
||||
|
||||
class VoteComment extends DTO
|
||||
class VoteComment extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
#[NullIsUndefined]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace sammo\DTO;
|
||||
|
||||
class VoteInfo extends DTO
|
||||
class VoteInfo extends \LDTO\DTO
|
||||
{
|
||||
public function __construct(
|
||||
public int $id,
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace sammo;
|
||||
|
||||
use sammo\Enums\MessageType;
|
||||
|
||||
class DiplomaticMessage extends Message{
|
||||
|
||||
const ACCEPTED = 1;
|
||||
@@ -18,7 +20,7 @@ class DiplomaticMessage extends Message{
|
||||
protected $validDiplomacy = true;
|
||||
|
||||
public function __construct(
|
||||
string $msgType,
|
||||
MessageType $msgType,
|
||||
MessageTarget $src,
|
||||
MessageTarget $dest,
|
||||
string $msg,
|
||||
@@ -27,7 +29,7 @@ class DiplomaticMessage extends Message{
|
||||
array $msgOption
|
||||
)
|
||||
{
|
||||
if ($msgType !== self::MSGTYPE_DIPLOMACY){
|
||||
if ($msgType !== MessageType::diplomacy){
|
||||
throw new \InvalidArgumentException('DiplomaticMessage msgType');
|
||||
}
|
||||
|
||||
@@ -208,7 +210,7 @@ class DiplomaticMessage extends Message{
|
||||
|
||||
$josaYi = JosaUtil::pick($this->src->nationName, '이');
|
||||
$newMsg = new Message(
|
||||
self::MSGTYPE_NATIONAL,
|
||||
MessageType::national,
|
||||
$this->dest,
|
||||
$this->src,
|
||||
"【외교】{$year}년 {$month}월: {$this->src->nationName}{$josaYi} {$this->dest->nationName}에게 제안한 {$this->diplomacyDetail}",
|
||||
@@ -224,7 +226,7 @@ class DiplomaticMessage extends Message{
|
||||
$newMsg->send();
|
||||
|
||||
$newMsg = new Message(
|
||||
self::MSGTYPE_DIPLOMACY,
|
||||
MessageType::diplomacy,
|
||||
$this->dest,
|
||||
$this->src,
|
||||
"【외교】{$year}년 {$month}월: {$this->src->nationName}{$josaYi} {$this->dest->nationName}에게 제안한 {$this->diplomacyDetail}",
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
namespace sammo\Enums;
|
||||
|
||||
/**
|
||||
* API 호출 결과가 false이면서, 대상 API가 처리할 수 없는 추가 동작이 있는 경우 사용.
|
||||
* 예시: 턴을 예약해야 하지만, 장수가 사망하여 게이트웨이로 이동해야함.
|
||||
*/
|
||||
enum APIRecoveryType: string{
|
||||
case Login = 'login';//로그인 재시도부터 시작한다
|
||||
case TwoFactorAuth = '2fa';//로그인은 가능하지만 인증코드 입력이 필요하다
|
||||
case Gateway = 'gateway';//로그인 완료. 게임 서버 리스트를 띄워야한다
|
||||
case GameLogin = 'game_login';//서버 업데이트 등으로 다시 게임 정보 수신 필요
|
||||
case GameQuota = 'game_quota';//접속 제한
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
namespace sammo\Enums;
|
||||
|
||||
/**
|
||||
* City Table column
|
||||
* schemal.sql과 일치
|
||||
*/
|
||||
enum CityColumn: string{
|
||||
case city = 'city';
|
||||
case name = 'name';
|
||||
case level = 'level';
|
||||
case nation = 'nation';
|
||||
case supply = 'supply';
|
||||
case front = 'front';
|
||||
case pop = 'pop';
|
||||
case pop_max = 'pop_max';
|
||||
case agri = 'agri';
|
||||
case agri_max = 'agri_max';
|
||||
case comm = 'comm';
|
||||
case comm_max = 'comm_max';
|
||||
case secu = 'secu';
|
||||
case secu_max = 'secu_max';
|
||||
case trust = 'trust';
|
||||
case trade = 'trade';
|
||||
case dead = 'dead';
|
||||
case def = 'def';
|
||||
case def_max = 'def_max';
|
||||
case wall = 'wall';
|
||||
case wall_max = 'wall_max';
|
||||
case officer_set = 'officer_set';
|
||||
case state = 'state';
|
||||
case region = 'region';
|
||||
case term = 'term';
|
||||
case conflict = 'conflict';
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
namespace sammo\Enums;
|
||||
|
||||
/**
|
||||
* General Table column
|
||||
* schemal.sql과 일치
|
||||
*/
|
||||
enum GeneralColumn: string{
|
||||
case no = 'no';
|
||||
case owner = 'owner';
|
||||
case npcmsg = 'npcmsg';
|
||||
case npc = 'npc';
|
||||
case npc_org = 'npc_org';
|
||||
case affinity = 'affinity';
|
||||
case bornyear = 'bornyear';
|
||||
case deadyear = 'deadyear';
|
||||
case newmsg = 'newmsg';
|
||||
case con = 'con';
|
||||
case connect = 'connect';
|
||||
case refresh = 'refresh';
|
||||
case logcnt = 'logcnt';
|
||||
case refcnt = 'refcnt';
|
||||
case picture = 'picture';
|
||||
case imgsvr = 'imgsvr';
|
||||
case name = 'name';
|
||||
case owner_name = 'owner_name';
|
||||
case nation = 'nation';
|
||||
case city = 'city';
|
||||
case troop = 'troop';
|
||||
case leadership = 'leadership';
|
||||
case leadership_exp = 'leadership_exp';
|
||||
case strength = 'strength';
|
||||
case strength_exp = 'strength_exp';
|
||||
case intel = 'intel';
|
||||
case intel_exp = 'intel_exp';
|
||||
case injury = 'injury';
|
||||
case experience = 'experience';
|
||||
case dedication = 'dedication';
|
||||
case dex1 = 'dex1';
|
||||
case dex2 = 'dex2';
|
||||
case dex3 = 'dex3';
|
||||
case dex4 = 'dex4';
|
||||
case dex5 = 'dex5';
|
||||
case officer_level = 'officer_level';
|
||||
case officer_city = 'officer_city';
|
||||
case permission = 'permission';
|
||||
case gold = 'gold';
|
||||
case rice = 'rice';
|
||||
case crew = 'crew';
|
||||
case crewtype = 'crewtype';
|
||||
case train = 'train';
|
||||
case atmos = 'atmos';
|
||||
case weapon = 'weapon';
|
||||
case book = 'book';
|
||||
case horse = 'horse';
|
||||
case item = 'item';
|
||||
case turntime = 'turntime';
|
||||
case recent_war = 'recent_war';
|
||||
case makelimit = 'makelimit';
|
||||
case killturn = 'killturn';
|
||||
case lastconnect = 'lastconnect';
|
||||
case lastrefresh = 'lastrefresh';
|
||||
case ip = 'ip';
|
||||
case block = 'block';
|
||||
case dedlevel = 'dedlevel';
|
||||
case explevel = 'explevel';
|
||||
case age = 'age';
|
||||
case startage = 'startage';
|
||||
case belong = 'belong';
|
||||
case betray = 'betray';
|
||||
case personal = 'personal';
|
||||
case special = 'special';
|
||||
case specage = 'specage';
|
||||
case special2 = 'special2';
|
||||
case specage2 = 'specage2';
|
||||
case defence_train = 'defence_train';
|
||||
case tnmt = 'tnmt';
|
||||
case myset = 'myset';
|
||||
case tournament = 'tournament';
|
||||
case newvote = 'newvote';
|
||||
case last_turn = 'last_turn';
|
||||
case aux = 'aux';
|
||||
case penalty = 'penalty';
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\Enums;
|
||||
|
||||
enum MessageType: string
|
||||
{
|
||||
case private = 'private';
|
||||
case public = 'public';
|
||||
case national = 'national';
|
||||
case diplomacy = 'diplomacy';
|
||||
//TODO: System을 정식으로 추가해야함.
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\Event\Action;
|
||||
|
||||
use sammo\DB;
|
||||
|
||||
class AddGlobalBetray extends \sammo\Event\Action
|
||||
{
|
||||
public function __construct(private int $cnt = 1, private int $ifMax = 0)
|
||||
{
|
||||
}
|
||||
|
||||
public function run(array $env)
|
||||
{
|
||||
$db = DB::db();
|
||||
$db->update('general', [
|
||||
'betray' => $db->sqleval('betray + %i', $this->cnt),
|
||||
], 'betray <= %i', $this->ifMax);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class CreateManyNPC extends \sammo\Event\Action
|
||||
|
||||
protected function generateNPC($env, int $cnt)
|
||||
{
|
||||
$pickTypeList = ['무' => 1, '지' => 1];
|
||||
$pickTypeList = ['무' => 0.333, '지' => 0.333, '무지' => 0.334];
|
||||
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\Event\Action;
|
||||
|
||||
use sammo\ActionLogger;
|
||||
use sammo\CityConst;
|
||||
use sammo\DB;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Util;
|
||||
use sammo\General;
|
||||
use sammo\JosaUtil;
|
||||
use sammo\LiteHashDRBG;
|
||||
use sammo\RandUtil;
|
||||
use sammo\UniqueConst;
|
||||
|
||||
class LostUniqueItem extends \sammo\Event\Action
|
||||
{
|
||||
public function __construct(
|
||||
private float $lostProb = 0.1,
|
||||
) {
|
||||
}
|
||||
|
||||
public function run(array $env)
|
||||
{
|
||||
$db = DB::db();
|
||||
|
||||
$generalIDList = $db->queryFirstColumn("SELECT `no` FROM general WHERE npc <= 1");
|
||||
if (!$generalIDList) {
|
||||
return;
|
||||
}
|
||||
$generals = General::createGeneralObjListFromDB($generalIDList);
|
||||
|
||||
$lostItems = [];
|
||||
$totalLostCnt = 0;
|
||||
|
||||
$year = $env['year'];
|
||||
$month = $env['month'];
|
||||
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
|
||||
UniqueConst::$hiddenSeed,
|
||||
'LostUniqueItem',
|
||||
$year,
|
||||
$month,
|
||||
)));
|
||||
|
||||
$maxLostByGenCnt = 0;
|
||||
$maxLostGenList = [];
|
||||
|
||||
foreach ($generals as $general) {
|
||||
$itemList = $general->getItems();
|
||||
$didLoseItem = false;
|
||||
$lostByGenCnt = 0;
|
||||
|
||||
foreach ($itemList as $itemType => $item) {
|
||||
if ($item->isBuyable()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
$logger = $general->getLogger();
|
||||
|
||||
if ($rng->nextBool($this->lostProb)) {
|
||||
$itemName = $item->getName();
|
||||
$itemRawName = $item->getRawName();
|
||||
$josaUl = JosaUtil::pick($itemRawName, '을');
|
||||
$lostItems[$itemName] = 1;
|
||||
$totalLostCnt++;
|
||||
$lostByGenCnt++;
|
||||
$general->setItem($itemType, 'None');
|
||||
$didLoseItem = true;
|
||||
$logger->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 잃었습니다.");
|
||||
}
|
||||
}
|
||||
|
||||
if (!$didLoseItem) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$general->applyDB($db);
|
||||
|
||||
if ($maxLostByGenCnt < $lostByGenCnt) {
|
||||
$maxLostByGenCnt = $lostByGenCnt;
|
||||
$maxLostGenList = [$general->getName()];
|
||||
} else if ($maxLostByGenCnt === $lostByGenCnt) {
|
||||
$maxLostGenList[] = $general->getName();
|
||||
}
|
||||
}
|
||||
|
||||
$logger = new ActionLogger(0, 0, $year, $month);
|
||||
if ($totalLostCnt == 0) {
|
||||
$logger->pushGlobalHistoryLog("<R><b>【망실】</b></>어떤 아이템도 잃지 않았습니다!");
|
||||
} else {
|
||||
$genCnt = count($maxLostGenList);
|
||||
if($genCnt > 4){
|
||||
$maxLostGenList = array_slice($maxLostGenList, 0, 4);
|
||||
|
||||
}
|
||||
$maxLostGenListStr = implode(', ', $maxLostGenList);
|
||||
|
||||
if($genCnt > 4){
|
||||
$maxLostGenListStr .= ' 외 ' . ($genCnt - 4) . '명';
|
||||
}
|
||||
$josaYi = JosaUtil::pick($maxLostGenListStr, '이');
|
||||
|
||||
$logger->pushGlobalHistoryLog("<R><b>【망실】</b></>불운하게도 <Y>{$maxLostGenListStr}</>{$josaYi} 한 번에 유니크 <C>{$maxLostByGenCnt}</>종을 잃었습니다! (총 <C>{$totalLostCnt}</>개)");
|
||||
}
|
||||
$logger->flush();
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ use \sammo\Util;
|
||||
use \sammo\DB;
|
||||
use sammo\DTO\BettingInfo;
|
||||
use sammo\DTO\SelectItem;
|
||||
use sammo\Enums\MessageType;
|
||||
use sammo\Json;
|
||||
use sammo\KVStorage;
|
||||
use sammo\Message;
|
||||
@@ -138,7 +139,7 @@ class OpenNationBetting extends \sammo\Event\Action
|
||||
GetImageURL($general['imgsvr'], $general['picture'])
|
||||
);
|
||||
$msg = new Message(
|
||||
Message::MSGTYPE_PRIVATE,
|
||||
MessageType::private,
|
||||
$src,
|
||||
$dest,
|
||||
$text,
|
||||
|
||||
@@ -46,6 +46,8 @@ class GameConstBase
|
||||
public static $sabotageDefaultProb = 0.35;
|
||||
/** @var int 계략시 확률 가중치(수치가 클수록 변화가 적음 : (지력차/$firing + $basefiring)*/
|
||||
public static $sabotageProbCoefByStat = 300;
|
||||
/** @var float 인원수 별 계략 방어 가중치 */
|
||||
public static $sabotageDefenceCoefByGeneralCnt = 0.04;
|
||||
/** @var int 계략시 최소 수치 감소량*/
|
||||
public static $sabotageDamageMin = 100;
|
||||
/** @var int 계략시 최대 수치 감소량*/
|
||||
@@ -202,6 +204,11 @@ class GameConstBase
|
||||
[20, 4]
|
||||
];
|
||||
|
||||
public static $minTurnDieOnPrestart = 2;
|
||||
|
||||
public static $uniqueTrialCoef = 1;
|
||||
public static $maxUniqueTrialProb = 0.25;
|
||||
|
||||
public static $maxAvailableWarSettingCnt = 10;
|
||||
public static $incAvailableWarSettingCnt = 2;
|
||||
|
||||
@@ -368,9 +375,9 @@ class GameConstBase
|
||||
'che_의병모집',
|
||||
'che_이호경식',
|
||||
'che_급습',
|
||||
'che_피장파장',
|
||||
],
|
||||
'기타' => [
|
||||
'che_피장파장',
|
||||
'che_국기변경',
|
||||
'che_국호변경',
|
||||
]
|
||||
@@ -431,5 +438,13 @@ class GameConstBase
|
||||
["NoticeToHistoryLog", "<S>출병 제한이 풀렸습니다.</>", ActionLogger::EVENT_YEAR_MONTH],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
"month", 2000,
|
||||
["DateRelative", "==", 4, 1],
|
||||
["NoticeToHistoryLog", "<S>이제부터 하야, 망명시 패널티가 적용됩니다.</>", ActionLogger::EVENT_YEAR_MONTH],
|
||||
["AddGlobalBetray", 1, 0],
|
||||
["AddGlobalBetray", 1, 1],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
@@ -115,16 +115,16 @@ class GameUnitConstBase{
|
||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||
['표준적인 궁병입니다.','궁병은 선제사격을 하는 병종입니다.'],
|
||||
null, ['che_궁병선제사격']
|
||||
null, ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
[
|
||||
1201, self::T_ARCHER, '궁기병',
|
||||
100, 100, 8, 20, 0, 11, 12,
|
||||
1000, null, ['동이'], 0,
|
||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||
['말을 타고 잘 피합니다.'],
|
||||
null, ['che_궁병선제사격']
|
||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.9, self::T_SIEGE=>1.2],
|
||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.1, self::T_SIEGE=>0.8],
|
||||
['말을 타고 잘 피합니다. 특히 다른 궁병보다 보병에게 조금 더 강합니다.'],
|
||||
null, ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
[
|
||||
1202, self::T_ARCHER, '연노병',
|
||||
@@ -133,7 +133,7 @@ class GameUnitConstBase{
|
||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||
['화살을 연사합니다.'],
|
||||
null, ['che_궁병선제사격']
|
||||
null, ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
[
|
||||
1203, self::T_ARCHER, '강궁병',
|
||||
@@ -142,7 +142,7 @@ class GameUnitConstBase{
|
||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||
['강건한 궁병입니다.'],
|
||||
null, ['che_궁병선제사격']
|
||||
null, ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
[
|
||||
1204, self::T_ARCHER, '석궁병',
|
||||
@@ -151,7 +151,7 @@ class GameUnitConstBase{
|
||||
[self::T_CAVALRY=>1.2, self::T_FOOTMAN=>0.8, self::T_SIEGE=>1.2],
|
||||
[self::T_CAVALRY=>0.8, self::T_FOOTMAN=>1.2, self::T_SIEGE=>0.8],
|
||||
['강력한 화살을 쏩니다.'],
|
||||
null, ['che_궁병선제사격']
|
||||
null, ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
|
||||
[
|
||||
@@ -316,7 +316,7 @@ class GameUnitConstBase{
|
||||
[self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112],
|
||||
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
|
||||
['높은 구조물 위에서 공격합니다.'],
|
||||
['che_성벽부상무효'], null
|
||||
['che_성벽부상무효'], ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
[
|
||||
1501, self::T_SIEGE, '충차',
|
||||
@@ -329,19 +329,19 @@ class GameUnitConstBase{
|
||||
],
|
||||
[
|
||||
1502, self::T_SIEGE, '벽력거',
|
||||
200, 100, 6, 5, 0, 20, 5,
|
||||
150, 100, 6, 5, 0, 20, 5,
|
||||
3000, ['업'], null, 0,
|
||||
[self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112],
|
||||
[self::T_FOOTMAN=>0.833, self::T_ARCHER=>0.833, self::T_CAVALRY=>0.833, self::T_WIZARD=>0.833, 1106=>0.909],
|
||||
['상대에게 돌덩이를 날립니다.'],
|
||||
['che_성벽부상무효'], null
|
||||
['che_성벽부상무효'], ['che_선제사격시도', 'che_선제사격발동']
|
||||
],
|
||||
[
|
||||
1503, self::T_SIEGE, '목우',
|
||||
50, 200, 5, 0, 0, 15, 5,
|
||||
3000, ['성도'], null, 0,
|
||||
[self::T_FOOTMAN=>0.8, self::T_ARCHER=>0.8, self::T_CAVALRY=>0.8, self::T_WIZARD=>0.8],
|
||||
[self::T_FOOTMAN=>1.2, self::T_ARCHER=>1.2, self::T_CAVALRY=>1.2, self::T_WIZARD=>1.2],
|
||||
[self::T_FOOTMAN=>1.25, self::T_ARCHER=>1.25, self::T_CAVALRY=>1.25, self::T_WIZARD=>1.25, self::T_CASTLE=>1.8, 1106=>1.112],
|
||||
[self::T_FOOTMAN=>1, self::T_ARCHER=>1, self::T_CAVALRY=>1, self::T_WIZARD=>1, 1106=>1],
|
||||
['상대를 저지하는 특수병기입니다.'],
|
||||
['che_성벽부상무효'], ['che_저지시도', 'che_저지발동']
|
||||
]
|
||||
|
||||
@@ -27,7 +27,7 @@ class GameUnitDetail implements iAction{
|
||||
public function __construct(
|
||||
int $id,
|
||||
int $armType,
|
||||
string $name,
|
||||
string $name,
|
||||
int $attack,
|
||||
int $defence,
|
||||
int $speed,
|
||||
@@ -110,7 +110,7 @@ class GameUnitDetail implements iAction{
|
||||
}
|
||||
else if($this->armType == GameUnitConst::T_MISC){
|
||||
$ratio = $general->getIntel(true, true, true) +
|
||||
$general->getLeadership(true, true, true) +
|
||||
$general->getLeadership(true, true, true) +
|
||||
$general->getStrength(true, true, true);
|
||||
$ratio = $ratio*2/3 - 40;
|
||||
}
|
||||
@@ -174,7 +174,7 @@ class GameUnitDetail implements iAction{
|
||||
$defaultWar *= 1 + $this->speed / 2;
|
||||
$defaultWar /= Util::valueFit(1 - $this->avoid / 100, 0.1);
|
||||
$defaultWar *= 1 + $this->magicCoef / 2;
|
||||
return sqrt($defaultWar);
|
||||
return $defaultWar;
|
||||
}
|
||||
|
||||
public function isValid($ownCities, $ownRegions, $relativeYear, $tech){
|
||||
@@ -256,6 +256,6 @@ class GameUnitDetail implements iAction{
|
||||
}
|
||||
}
|
||||
return new WarUnitTriggerCaller(...$triggerList);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user