Compare commits

...
97 Commits
Author SHA1 Message Date
Hide_D 4357fb3874 국호 변경 warning 수정 2020-03-05 07:35:01 +09:00
Hide_D 225c356b2d 국호 변경 추가 2020-03-05 07:33:11 +09:00
Hide_D 0bb45979df ng_old_generals에 aux 반영 2020-03-05 06:53:15 +09:00
Hide_D b28ac27fba 내특 전특 초기화 추가 2020-03-05 06:48:15 +09:00
Hide_D 017d1b5dd9 general에 aux 추가 2020-03-05 06:39:02 +09:00
Hide_D a7b22748cd miniche_clean 2020-02-08 23:42:22 +09:00
Hide_D 4f2c08918a 핫픽스 효율 향상 2020-02-08 14:10:36 +09:00
Hide_D d2f6df270b NPC가 함부러 전쟁 상태를 바꾸지 않도록 변경 2020-02-08 14:10:32 +09:00
Hide_D 64b14b0c5d '대' 도시 이름 버그 수정 2020-01-30 16:34:07 +09:00
Hide_D 8394c9780c 테스트 기수용 맵 추가, 증축 비용 상수값 추가 2020-01-28 02:59:06 +09:00
Hide_D a5b404298b 징병에서는 기능 안뜨는 문제 수정 2020-01-28 02:18:58 +09:00
Hide_D ab48082bb8 징병 불가능한 병종도 표기 2020-01-28 02:15:51 +09:00
Hide_D 9094434c16 {} 참조 제거 2020-01-28 01:25:52 +09:00
Hide_D ddb971e41e 재 업데이트 2020-01-28 01:17:00 +09:00
Hide_D a8b3befca9 composer update 2020-01-28 01:16:04 +09:00
Hide_D e5bed62ca9 Medoo 수정 2020-01-28 01:11:59 +09:00
Hide_D 76b8a59f39 Revert "medoo only"
This reverts commit 2c31de1d6a.
2020-01-28 00:56:16 +09:00
Hide_D 4dbe30bb2b medoo only 2020-01-28 00:55:57 +09:00
Hide_D adcfcaa1ef Revert "composer reinstall"
This reverts commit d16736132c.
2020-01-28 00:44:38 +09:00
Hide_D da32f0067a composer reinstall 2020-01-28 00:43:48 +09:00
Hide_D 19be0c4560 Revert "package update 재도전"
This reverts commit 595ab6d7e5.
2020-01-28 00:31:53 +09:00
Hide_D f6e53746b2 package update 재도전 2020-01-28 00:30:41 +09:00
Hide_D 9cd40b213d Revert "composer package update"
This reverts commit e979959219.
2020-01-28 00:23:38 +09:00
Hide_D ed69eb5d7b composer package update 2020-01-28 00:22:43 +09:00
Hide_D ed95d5e933 버그 수정 2020-01-04 04:40:27 +09:00
Hide_D 53f3083b73 npc 워프 기준을 태수, 군사, 시중 모두 따르도록 변경. 워프 버그 수정 2020-01-04 04:00:15 +09:00
Hide_D 61df5ed809 버그 수정 2020-01-04 03:28:31 +09:00
Hide_D 7c1baa6cf1 공백지를 고려하지 않는 버그 수정 2020-01-04 03:26:50 +09:00
Hide_D 800d4f6cc9 출병에서 1칸 떨어진 도시를 제거 2020-01-04 01:25:29 +09:00
Hide_D 1ab45af036 출병을 '어택땅'으로 변경 2020-01-04 01:23:07 +09:00
Hide_D e9b5e4d4d1 같은 병종 숙련전환하면 늘어나기만 하는 버그 수정 2019-11-26 18:49:40 +09:00
Hide_D 65aa4c29a4 NPC 버그 수정, NPC 징병 룰 변경
징병시 최대 통솔 반영
발령 시 인구 바닥난 곳 고려 안하던 것 보정
징병 기준을 통솔과 관계없이 40000명인 경우에 시도하던 버그 수정
NPC는 30000 + 20000 일 경우에만 징병함.
2019-11-10 04:08:48 +09:00
Hide_D e75b6f2d5b miniche_b js 등록 2019-10-25 18:40:32 +09:00
Hide_D dbc758095f miniche_b 추가 2019-10-24 02:19:46 +09:00
Hide_D 57a94e4a7d 연감 버그 수정 2019-10-16 02:34:46 +09:00
Hide_D 50526383f9 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2019-10-16 02:32:51 +09:00
Hide_D 639b1dcac7 연감 출력 개선 2019-10-16 02:32:44 +09:00
Hide_D a984651888 포켓몬 맵 js 등록 2019-10-04 01:18:45 +09:00
Hide_D a8befe5478 찐 유저무쌍 추가 2019-10-03 23:39:47 +09:00
Hide_D 43ba732aad 기본 증축량 버그 수정 2019-10-03 21:15:52 +09:00
Hide_D 158068273e 포켓몬스터 전콘 안뜨는 문제 수정 2019-10-03 20:52:51 +09:00
Hide_D 94a00dbdac 포켓몬 v1 추가 2019-10-03 19:50:22 +09:00
Hide_D fedc7e5ef5 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2019-10-03 15:12:35 +09:00
Hide_D 78ff016def 감축 조건 변경, 증/감축시 변화량을 지정가능하도록 변경 2019-10-03 15:12:25 +09:00
Hide_D 30d8324a0a 핫픽스 2019-10-02 13:37:30 +09:00
Hide_D de1fa34922 병력없을 때 공격 루틴 타는 것 방지 2019-10-01 22:06:38 +09:00
Hide_D a74b9a5e80 서신전달 빈칸 입력 테스트 2019-09-28 11:54:19 +09:00
Hide_D 79a199cbd3 자동 진행 모드일 때 모반이 거의 항상 가능해지는 버그 수정 2019-09-28 07:56:32 +09:00
Hide_D 2f2062c9e5 랜임코드 버그 수정 2019-09-26 18:42:51 +09:00
Hide_D 1dcace7a62 자율행동 항상 유효 변경 2019-09-25 02:17:27 +09:00
Hide_D 8f107b56b3 서버에서 자율행동란에 시간 추가, tooltip에 copyable_info 추가 2019-09-25 02:14:49 +09:00
Hide_D 8c6afee7c9 부대장 사망의 경우도 고려 2019-09-24 07:34:55 +09:00
Hide_D d4982f3ed9 README.md 변경 2019-09-23 01:19:49 +09:00
Hide_D f2a785f2fc imagePull 기능 추가, 인스톨러 완성 2019-09-23 00:28:15 +09:00
Hide_D 6fafcfae4e 훈사 분리 2019-09-21 23:27:43 +09:00
Hide_D 33e075f669 훈사를 분리 2019-09-21 21:29:20 +09:00
Hide_D e5fc467c4e 버그 수정 2019-09-21 21:04:17 +09:00
Hide_D b7a5de49c6 표기 일부 변경 2019-09-21 18:09:37 +09:00
Hide_D 3f145abd6f 모훈사 기준을 징병 6회로 변경 2019-09-21 17:39:13 +09:00
Hide_D 4612834870 워프 기준, 쌀 삼팜 기준 변경 2019-09-21 14:41:23 +09:00
Hide_D 83c5609fad 징병 버그 수정 2 2019-09-21 11:42:10 +09:00
Hide_D d142056098 징병 안되는 버그 수정 2019-09-21 11:39:51 +09:00
Hide_D 4d8ecf4191 진짜로 삭턴 버그 수정 2019-09-21 02:44:00 +09:00
Hide_D af6c3f466d 삭턴 버그 수정 2019-09-21 02:38:06 +09:00
Hide_D 033a2d8674 삭턴 버그 수정 2019-09-21 02:35:15 +09:00
Hide_D 9079788b2b 삭턴 기준 변경 2019-09-21 02:33:39 +09:00
Hide_D 44ddb2e480 git fetch에도 -q 2019-09-21 02:28:49 +09:00
Hide_D 295ba84071 자동 행동 세부를 툴팁으로 2019-09-21 02:27:05 +09:00
Hide_D 8773250aab 초기 병종이 보병일 때 고정되는 버그 수정 2019-09-21 02:14:25 +09:00
Hide_D c5a4602fe1 옵션 표기 버그 수정 2019-09-21 02:11:54 +09:00
Hide_D 5f4c43baf6 Merge branch 'devel' into autorun 2019-09-21 02:07:26 +09:00
Hide_D 0ef3921e17 update 서버 변경 2019-09-21 02:06:49 +09:00
Hide_D efcf0f772e server checkout 추가2 2019-09-21 01:50:36 +09:00
Hide_D ccabe847bb 루트도 git tree-ish 지정 가능 2019-09-21 01:42:21 +09:00
Hide_D 45ed63ffe3 버그 수정 2019-09-21 01:38:29 +09:00
Hide_D 7bebbe3a16 징병, 모병 추가 2019-09-21 01:09:17 +09:00
Hide_D 53ba1db79f autorun_user 초기 세팅 2019-09-20 02:12:42 +09:00
Hide_D 76c306a122 npc AI를 '사전 턴' 수행 이후에 처리하도록 변경 2019-09-20 00:41:38 +09:00
Hide_D 89c2c163cb 서버 정보에 자동행동 표기 2019-09-20 00:35:13 +09:00
Hide_D 8826061266 autorun_user 인자 세팅 2019-09-20 00:05:40 +09:00
Hide_D e684877c94 리셋 화면에서 '휴식 턴 시 장수 턴' 추가 2019-09-19 02:21:51 +09:00
Hide_D 12c8152901 docker 메시지 수정 2019-09-19 01:16:21 +09:00
Hide_D 8ba20bf4d2 Docker를 이용한 설치 안내 2019-09-15 23:25:11 +09:00
Hide_D 0bc1ad09d1 년도 변경 2019-09-15 23:19:04 +09:00
Hide_D 231c79132a run_daemon 1분 유지 수정 2019-09-15 20:59:35 +09:00
Hide_D 089803c599 cron 수정 2019-09-15 20:53:23 +09:00
Hide_D 4ea373aff6 gitignore change 2019-09-15 20:08:57 +09:00
Hide_D 0d94b8c742 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2019-09-15 19:49:32 +09:00
Hide_D d444f19043 date_default_timezone_set 해제 2019-09-15 19:49:24 +09:00
Hide_D 87a0e73c96 인스톨러 버그 수정 2019-09-15 02:59:38 +09:00
Hide_D b5922095f0 인스톨러 임시 트윅 2019-09-15 02:50:10 +09:00
Hide_D 3fee29e9e9 setup_db에서 global_salt 추가 2019-09-15 00:55:57 +09:00
Hide_D 4e351b3be8 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2019-09-15 00:38:00 +09:00
Hide_D 3432b900df 설치 직후 기본 gitpath 변경 2019-09-15 00:37:46 +09:00
Hide_D fb7c67f317 빙의 안되는 버그 수정, 가입/빙의 시 락 2019-08-18 18:01:11 +09:00
Hide_D 28d5a5c39a 장수 생성시 빠르게 쿼리를 날려 중복 생성하는 것이 불가능하도록 2019-08-18 17:50:38 +09:00
Hide_D e2754511d9 부대탈퇴 시 propergation 처리 실수 수정 2019-08-18 00:46:39 +09:00
481 changed files with 16554 additions and 16557 deletions
+1 -7
View File
@@ -1,11 +1,4 @@
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
# 체섭 ignore
*.log
@@ -48,3 +41,4 @@ test.php
phpinfo.php
vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/*
*.sqlite3
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License
Copyright (c) 2018 Hide_D, 62che
Copyright (c) 2020 Hide_D, 62che
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+14 -9
View File
@@ -11,16 +11,21 @@
* <code>php-fpm</code> 권장
* php에서 curl, pdo-sqlite을 실행가능해야 합니다. (기본값: 지원)
* mysqlnd가 지원되어야합니다. (기본값: 지원)
* mysqli
* gd
* MariaDB 10.2.1 이상
* MySQL 5.6 이상도 가능하도록 할 예정입니다.
* 현재 MySQL은 지원하지 않습니다.
* <code>git</code>
* <code>curl</code>
Linux는 Ubuntu 16.04, Windows는 Windows 10에서 XAMPP를 사용한 환경에서 테스트되었습니다.
Linux는 Ubuntu 16.04, 18.04, Windows는 Windows 10에서 XAMPP를 사용한 환경에서 테스트되었습니다.
Docker를 이용한 설치는 계획중입니다.
## 설치
## Docker를 이용한 설치
https://storage.hided.net/gogs/devsam/docker 를 참고해 주세요.
## 수동 설치
본 게임은 <code>git</code>을 이용한 업그레이드 시스템을 구현하였으므로, <code>git</code>이 필요합니다.
또한 웹 서비스 데몬을 운영중인 사용자(일반적으로 <code>www-data</code>, <code>apache</code>)에게 디렉토리 권한이 주어져야합니다.
@@ -30,11 +35,11 @@ Docker를 이용한 설치는 계획중입니다.
웹 데몬 user가 <code>www-data</code>인 경우 다음과 같이 입력하여 최신 배포버전과 이미지 파일을 얻을 수 있습니다.
```
sudo -u www-data git clone ssh://git@storage.hided.net:2525/devsam/core.git
git clone ssh://git@storage.hided.net:2525/devsam/image.git
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/core.git
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/image.git
```
> 이미지는 git hook을 이용한 업데이트 기능을 제공하지만 아직 범용성 있는 설계가 되어있진 않습니다.
> 이미지는 hook/git_hook.php을 통해 동기화되며, 서버 설치 과정에 이미지 갱신 키를 지정하는 것으로 '훼' 서버 업데이트 시 동기화됩니다. 이미지 서버가 게임 서버와 별개여도 동작하나, php와 git을 지원해야합니다.
### 설치
@@ -47,9 +52,9 @@ Database 수는 로그인 관리 서버 1개, 내부 서버 7개로, 총 8개의
## 카카오로그인 연동
현재 카카오로그인 API KEY를 입력하는 작업이 설치과정에 추가되어있지 않습니다.
서버 설치 시 카카오 로그인 연동을 위한 API KEY를 입력습니다.
설치 후 <code>d_setting/KakaoKey.php</code>에서 API키를 입력해야 합니다.
만약 설치 이후 API KEY를 변경하고자 하는 경우 <code>d_setting/KakaoKey.php</code>에서 API키를 변경해야 합니다.
## 라이선스
+6 -1
View File
@@ -6,12 +6,17 @@
"GPL-2.0-or-later",
"proprietary"
],
"config": {
"platform": {
"php": "7.3"
}
},
"require": {
"brandonwamboldt/utilphp": "^1.1",
"sergeytsalkov/meekrodb": "^2.3",
"league/plates": "^3.3",
"guzzlehttp/guzzle": "^6.3",
"leafo/scssphp": "^0.7.5",
"scssphp/scssphp": "^1.0",
"monolog/monolog": "^1.23",
"firephp/firephp-core": "^0.4.0",
"vlucas/valitron": "^1.4",
Generated
+200 -123
View File
@@ -1,10 +1,10 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "3fceaf3c2925068c7e757ab12036e29e",
"content-hash": "b5b5695ed0b1b04fa672f99972d8caad",
"packages": [
{
"name": "brandonwamboldt/utilphp",
@@ -54,16 +54,16 @@
},
{
"name": "catfan/medoo",
"version": "v1.5.7",
"version": "v1.7.8",
"source": {
"type": "git",
"url": "https://github.com/catfan/Medoo.git",
"reference": "8d90cba0e8ff176028847527d0ea76fe41a06ecf"
"reference": "dd9d570584cfb1e09ec470608479b86e41d5b60d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/catfan/Medoo/zipball/8d90cba0e8ff176028847527d0ea76fe41a06ecf",
"reference": "8d90cba0e8ff176028847527d0ea76fe41a06ecf",
"url": "https://api.github.com/repos/catfan/Medoo/zipball/dd9d570584cfb1e09ec470608479b86e41d5b60d",
"reference": "dd9d570584cfb1e09ec470608479b86e41d5b60d",
"shasum": ""
},
"require": {
@@ -77,7 +77,7 @@
"ext-pdo_oci8": "For Oracle version 8 database",
"ext-pdo_pqsql": "For PostgreSQL database",
"ext-pdo_sqlite": "For SQLite database",
"ext-pdo_sqlsrv": "For MSSQL database"
"ext-pdo_sqlsrv": "For MSSQL database on both Window/Liunx platform"
},
"type": "framework",
"autoload": {
@@ -95,10 +95,11 @@
"email": "angel@catfan.me"
}
],
"description": "The lightest PHP database framework to accelerate development",
"description": "The lightweight PHP database framework to accelerate development",
"homepage": "https://medoo.in",
"keywords": [
"database",
"database library",
"lightweight",
"mariadb",
"mssql",
@@ -109,27 +110,27 @@
"sql",
"sqlite"
],
"time": "2018-06-14T18:59:08+00:00"
"time": "2019-12-19T05:04:34+00:00"
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.10.0",
"version": "v4.12.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "d85d39da4576a6934b72480be6978fb10c860021"
"reference": "a617e55bc62a87eec73bd456d146d134ad716f03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021",
"reference": "d85d39da4576a6934b72480be6978fb10c860021",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/a617e55bc62a87eec73bd456d146d134ad716f03",
"reference": "a617e55bc62a87eec73bd456d146d134ad716f03",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"require-dev": {
"simpletest/simpletest": "^1.1"
"simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
},
"type": "library",
"autoload": {
@@ -142,7 +143,7 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
"LGPL-2.1-or-later"
],
"authors": [
{
@@ -156,7 +157,7 @@
"keywords": [
"html"
],
"time": "2018-02-23T01:58:20+00:00"
"time": "2019-10-28T03:44:26+00:00"
},
{
"name": "firephp/firephp-core",
@@ -196,44 +197,46 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
"version": "6.5.2",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82",
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.4",
"guzzlehttp/psr7": "^1.6.1",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
"psr/log": "^1.0"
"psr/log": "^1.1"
},
"suggest": {
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.3-dev"
"dev-master": "6.5-dev"
}
},
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -257,7 +260,7 @@
"rest",
"web service"
],
"time": "2018-04-22T15:46:56+00:00"
"time": "2019-12-23T11:57:10+00:00"
},
{
"name": "guzzlehttp/promises",
@@ -312,32 +315,37 @@
},
{
"name": "guzzlehttp/psr7",
"version": "1.4.2",
"version": "1.6.1",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
"reference": "239400de7a173fe9901b9ac7c06497751f00727a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
},
"suggest": {
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "1.6-dev"
}
},
"autoload": {
@@ -367,65 +375,14 @@
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
"uri",
"url"
],
"time": "2017-03-20T17:10:46+00:00"
},
{
"name": "leafo/scssphp",
"version": "v0.7.7",
"source": {
"type": "git",
"url": "https://github.com/leafo/scssphp.git",
"reference": "1d656f8c02a3a69404bba6b28ec4e06edddf0f49"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/leafo/scssphp/zipball/1d656f8c02a3a69404bba6b28ec4e06edddf0f49",
"reference": "1d656f8c02a3a69404bba6b28ec4e06edddf0f49",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.6",
"squizlabs/php_codesniffer": "~2.5"
},
"bin": [
"bin/pscss"
],
"type": "library",
"autoload": {
"psr-4": {
"Leafo\\ScssPhp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Leaf Corcoran",
"email": "leafot@gmail.com",
"homepage": "http://leafo.net"
}
],
"description": "scssphp is a compiler for SCSS written in PHP.",
"homepage": "http://leafo.github.io/scssphp/",
"keywords": [
"css",
"less",
"sass",
"scss",
"stylesheet"
],
"time": "2018-07-22T01:22:08+00:00"
"time": "2019-07-01T23:21:34+00:00"
},
{
"name": "league/plates",
@@ -484,16 +441,16 @@
},
{
"name": "monolog/monolog",
"version": "1.23.0",
"version": "1.25.3",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
"reference": "fa82921994db851a8becaf3787a9e73c5976b6f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fa82921994db851a8becaf3787a9e73c5976b6f1",
"reference": "fa82921994db851a8becaf3787a9e73c5976b6f1",
"shasum": ""
},
"require": {
@@ -558,7 +515,7 @@
"logging",
"psr-3"
],
"time": "2017-06-19T01:22:40+00:00"
"time": "2019-12-20T14:15:16+00:00"
},
{
"name": "pguardiario/phpuri",
@@ -720,16 +677,16 @@
},
{
"name": "psr/log",
"version": "1.0.2",
"version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
"shasum": ""
},
"require": {
@@ -738,7 +695,7 @@
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.1.x-dev"
}
},
"autoload": {
@@ -763,7 +720,108 @@
"psr",
"psr-3"
],
"time": "2016-10-10T12:19:37+00:00"
"time": "2019-11-01T11:05:21+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "scssphp/scssphp",
"version": "1.0.6",
"source": {
"type": "git",
"url": "https://github.com/scssphp/scssphp.git",
"reference": "5b3c9d704950d8f9637f5110c36c281ec47dc13c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/5b3c9d704950d8f9637f5110c36c281ec47dc13c",
"reference": "5b3c9d704950d8f9637f5110c36c281ec47dc13c",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-json": "*",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3",
"squizlabs/php_codesniffer": "~2.5",
"twbs/bootstrap": "~4.3",
"zurb/foundation": "~6.5"
},
"bin": [
"bin/pscss"
],
"type": "library",
"autoload": {
"psr-4": {
"ScssPhp\\ScssPhp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anthon Pang",
"email": "apang@softwaredevelopment.ca",
"homepage": "https://github.com/robocoder"
},
{
"name": "Cédric Morin",
"email": "cedric@yterium.com",
"homepage": "https://github.com/Cerdic"
}
],
"description": "scssphp is a compiler for SCSS written in PHP.",
"homepage": "http://scssphp.github.io/scssphp/",
"keywords": [
"css",
"less",
"sass",
"scss",
"stylesheet"
],
"time": "2019-12-12T05:00:52+00:00"
},
{
"name": "sergeytsalkov/meekrodb",
@@ -810,29 +868,34 @@
},
{
"name": "symfony/lock",
"version": "v4.1.1",
"version": "v4.4.3",
"source": {
"type": "git",
"url": "https://github.com/symfony/lock.git",
"reference": "d508b5dd92272cb74300396ecaadde969d0f7976"
"reference": "6c4f5b620871cfef5b004fc57f2ca74572ae03b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/lock/zipball/d508b5dd92272cb74300396ecaadde969d0f7976",
"reference": "d508b5dd92272cb74300396ecaadde969d0f7976",
"url": "https://api.github.com/repos/symfony/lock/zipball/6c4f5b620871cfef5b004fc57f2ca74572ae03b3",
"reference": "6c4f5b620871cfef5b004fc57f2ca74572ae03b3",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"psr/log": "~1.0"
},
"conflict": {
"doctrine/dbal": "<2.5"
},
"require-dev": {
"doctrine/dbal": "~2.5",
"mongodb/mongodb": "~1.1",
"predis/predis": "~1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
"dev-master": "4.4-dev"
}
},
"autoload": {
@@ -848,13 +911,13 @@
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
},
{
"name": "Jérémy Derussé",
"email": "jeremy@derusse.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Lock Component",
@@ -867,20 +930,20 @@
"redlock",
"semaphore"
],
"time": "2018-06-21T11:15:46+00:00"
"time": "2020-01-04T13:00:46+00:00"
},
{
"name": "vlucas/valitron",
"version": "v1.4.3",
"version": "v1.4.7",
"source": {
"type": "git",
"url": "https://github.com/vlucas/valitron.git",
"reference": "3c5463315bfa23b17f8949b100a960d035234e43"
"reference": "a03072bed1679660200766d134507a30193eaf6d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/valitron/zipball/3c5463315bfa23b17f8949b100a960d035234e43",
"reference": "3c5463315bfa23b17f8949b100a960d035234e43",
"url": "https://api.github.com/repos/vlucas/valitron/zipball/a03072bed1679660200766d134507a30193eaf6d",
"reference": "a03072bed1679660200766d134507a30193eaf6d",
"shasum": ""
},
"require": {
@@ -916,28 +979,29 @@
"validation",
"validator"
],
"time": "2018-05-06T10:45:26+00:00"
"time": "2019-08-29T19:49:43+00:00"
},
{
"name": "xemlock/htmlpurifier-html5",
"version": "v0.1.7",
"version": "v0.1.11",
"source": {
"type": "git",
"url": "https://github.com/xemlock/htmlpurifier-html5.git",
"reference": "b4b35e51ec75e0207c23035f7d9a354bdcdac359"
"reference": "f0d563f9fd4a82a3d759043483f9a94c0d8c2255"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/xemlock/htmlpurifier-html5/zipball/b4b35e51ec75e0207c23035f7d9a354bdcdac359",
"reference": "b4b35e51ec75e0207c23035f7d9a354bdcdac359",
"url": "https://api.github.com/repos/xemlock/htmlpurifier-html5/zipball/f0d563f9fd4a82a3d759043483f9a94c0d8c2255",
"reference": "f0d563f9fd4a82a3d759043483f9a94c0d8c2255",
"shasum": ""
},
"require": {
"ezyang/htmlpurifier": "^4.7",
"ezyang/htmlpurifier": "^4.8",
"php": ">=5.2"
},
"require-dev": {
"phpunit/phpunit": "4.7.*|5.7.*"
"php-coveralls/php-coveralls": "^1.1|^2.1",
"phpunit/phpunit": ">=4.7 <8.0"
},
"type": "library",
"autoload": {
@@ -955,8 +1019,18 @@
"email": "xemlock@gmail.com"
}
],
"description": "HTML Purifier definitions for HTML5 elements",
"time": "2018-06-07T14:30:17+00:00"
"description": "HTML5 element definitions for HTML Purifier",
"keywords": [
"HTML5",
"Purifier",
"html",
"htmlpurifier",
"security",
"tidy",
"validator",
"xss"
],
"time": "2019-08-07T17:19:21+00:00"
}
],
"packages-dev": [],
@@ -966,5 +1040,8 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
"platform-dev": [],
"platform-overrides": {
"php": "7.3"
}
}
BIN
View File
Binary file not shown.
+11
View File
@@ -166,6 +166,17 @@ a.samButton.disabled {
content:'】'
}
.tooltip_copyable_info .tooltiptext{
display: inline;
color: rgba(0,0,0,0);
font-size: 0;
}
.tooltiptext {
display: none;
}
.hidden_but_copyable{
color: rgba(0,0,0,0);
font-size: 0;
}
-1
View File
@@ -3,7 +3,6 @@ namespace sammo;
define('ROOT', realpath(__dir__.'/..'));
setlocale(LC_ALL, 'ko_KR.UTF-8');
date_default_timezone_set('Asia/Seoul');
mb_internal_encoding("UTF-8");
mb_http_output('UTF-8');
mb_regex_encoding('UTF-8');
+32
View File
@@ -98,6 +98,38 @@ require(__dir__.'/../vendor/autoload.php');
</div>
</div>
<div class="form-group row">
<label for="image_request_key" class="col-sm-4 col-form-label">이미지 갱신 키</label>
<div class="input-group col-sm-8">
<input type="text" class="form-control" name="image_request_key" id="image_request_key"
placeholder="이미지 서버의 hook/HashKey.php의 값과 동일하게"
value="" />
<div class="input-group-append">
<button id="btn_random_generate_key" class="btn btn-secondary" type="button">랜덤 생성</button>
</div>
</div>
</div>
<hr style="width:100%; border-top: 1px solid lightgray;">
<div class="form-group row">
<label for="kakao_rest_key" class="col-sm-4 col-form-label">카카오 API Rest Key</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="kakao_rest_key" id="kakao_rest_key"
placeholder="카카오톡 API의 Rest Key"
value="" />
</div>
</div>
<div class="form-group row">
<label for="kakao_admin_key" class="col-sm-4 col-form-label">카카오 API Admin Key</label>
<div class="col-sm-8">
<input type="text" class="form-control" name="kakao_admin_key" id="kakao_admin_key"
placeholder="카카오톡 API의 Admin Key"
value="" />
</div>
</div>
<div class="form-group row">
<div class="col-sm-4"></div>
<div class="col-sm-8">
+21 -2
View File
@@ -11,6 +11,11 @@ $dbName = Util::getReq('db_name');
$servHost = Util::getReq('serv_host');
$sharedIconPath = Util::getReq('shared_icon_path');
$gameImagePath = Util::getReq('game_image_path');
$imageRequestKey = Util::getReq('image_request_key');
$kakaoRESTKey = Util::getReq('kakao_rest_key', 'string', '');
$kakaoAdminKey = Util::getReq('kakao_admin_key', 'string', '');
if (!$host || !$port || !$username || !$password || !$dbName || !$servHost || !$sharedIconPath || !$gameImagePath) {
Json::die([
@@ -186,6 +191,8 @@ $globalSalt = bin2hex(random_bytes(16));
$sharedIconPath = WebUtil::resolveRelativePath($sharedIconPath, $servHost);
$gameImagePath = WebUtil::resolveRelativePath($gameImagePath, $servHost);
$imageRequestPath = WebUtil::resolveRelativePath($gameImagePath.'/../hook/git_pull.php', $servHost);
$imageKeyInstallPath = WebUtil::resolveRelativePath($gameImagePath.'/../hook/InstallKey.php', $servHost);
$result = Util::generateFileUsingSimpleTemplate(
__dir__.'/templates/ServConfig.orig.php',
@@ -193,11 +200,17 @@ $result = Util::generateFileUsingSimpleTemplate(
[
'serverBasePath'=>$servHost,
'sharedIconPath'=>$sharedIconPath,
'gameImagePath'=>$gameImagePath
'gameImagePath'=>$gameImagePath,
'imageRequestPath'=>$imageRequestPath,
'imageRequestKey'=>$imageRequestKey
],
true
);
if($imageRequestKey){
@file_get_contents($imageKeyInstallPath.'?key='.$imageRequestKey);
}
if ($result !== true) {
Json::die([
'result'=>false,
@@ -263,10 +276,15 @@ $result = Util::generateFileUsingSimpleTemplate(
]
);
$kakaoRedirectURI = WebUtil::resolveRelativePath('oauth_kakao/oauth.php', $servHost.'/');
Util::generateFileUsingSimpleTemplate(
__dir__.'/templates/KakaoKey.orig.php',
ROOT.'/d_setting/KakaoKey.php',
[
'REST_API_KEY'=>$kakaoRESTKey,
'ADMIN_KEY'=>$kakaoAdminKey,
'REDIRECT_URI'=>$kakaoRedirectURI
],
true
);
@@ -280,5 +298,6 @@ if ($result !== true) {
Json::die([
'result'=>true,
'reason'=>'success'
'reason'=>'success',
'globalSalt'=>$globalSalt
]);
+9
View File
@@ -10,6 +10,8 @@ class ServConfig
public static $serverWebPath = '_tK_serverBasePath_';
public static $sharedIconPath = '_tK_sharedIconPath_';
public static $gameImagePath = "_tK_gameImagePath_";
public static $imageRequestPath = "_tK_imageRequestPath_";
public static $imageRequestKey = '_tK_imageRequestKey_';
public static function getSharedIconPath(string $filepath='') : string
{
@@ -32,6 +34,13 @@ class ServConfig
return static::$gameImagePath;
}
public static function getImagePullURI() : string
{
$now = time();
$req_hash = Util::hashPassword(sprintf("%016x",$now), static::$imageRequestKey);
return static::$imageRequestPath."?req={$req_hash}&time={$now}";
}
/**
* 서버 주소 반환. 서버의 경로가 하부 디렉토리인 경우에 하부 디렉토리까지 포함
+61 -1
View File
@@ -88,6 +88,59 @@
background-size: 700px 500px;
}
/*미니체 지도*/
.map_theme_miniche_b.map_spring .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_spring.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b.map_summer .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_summer.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b.map_fall .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_fall.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b.map_winter .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_winter.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_b .map_bgroad{
background: url('_tK_gameImagePath_/map/che/miniche_road.png') no-repeat;
background-size: 700px 500px;
}
/*미니체 지도*/
.map_theme_miniche_clean.map_spring .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_spring.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean.map_summer .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_summer.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean.map_fall .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_fall.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean.map_winter .map_bglayer1{
background: url('_tK_gameImagePath_/map/che/bg_winter.jpg') no-repeat;
background-size: 700px 500px;
}
.map_theme_miniche_clean .map_bgroad{
background: url('_tK_gameImagePath_/map/che/miniche_road.png') no-repeat;
background-size: 700px 500px;
}
/*루드라사움 지도*/
.map_theme_ludo_rathowm .map_bglayer1{
background: url('_tK_gameImagePath_/map/ludo_rathowm/back.jpg') no-repeat;
@@ -109,4 +162,11 @@
.map_theme_chess .map_bglayer1{
background: url('_tK_gameImagePath_/map/chess/chessboard.png') no-repeat;
background-size: 700px 500px;
}
}
/*포켓몬 v1 지도*/
.map_theme_pokemon_v1 .map_bglayer1{
background: url('_tK_gameImagePath_/map/pokemon_v1/back_pal8.png') no-repeat;
background-size: 700px 500px;
}
+14 -18
View File
@@ -86,6 +86,8 @@ if ($month <= 0) {
$month += 12;
}
$history = $db->queryFirstRow('SELECT log,genlog,nation,power,gen,city FROM history WHERE server_id = %s AND year = %i AND month = %i', $serverID, $year, $month);
?>
<!DOCTYPE html>
<html>
@@ -101,12 +103,19 @@ if ($month <= 0) {
<?=WebUtil::printJS('js/common.js')?>
<?=WebUtil::printJS("js/map/theme_{$mapTheme}.js")?>
<?=WebUtil::printJS('js/map.js')?>
<?=WebUtil::printJS('js/history.js')?>
<?=WebUtil::printCSS('../e_lib/bootstrap.min.css')?>
<?=WebUtil::printCSS('../d_shared/common.css')?>
<?=WebUtil::printCSS('css/common.css')?>
<?=WebUtil::printCSS('css/map.css')?>
<script>
var startYear = <?=$s_year?>;
var startMonth = <?=$s_month?>;
var lastYear = <?=$e_year?>;
var lastMonth = <?=$e_month?>;
var selectYear = <?=$year?>;
var selectMonth = <?=$month?>;
</script>
</head>
<body>
@@ -116,22 +125,9 @@ if ($month <= 0) {
<form name=form1 method=post>
년월 선택 :
<input type=submit name=btn value="◀◀ 이전달">
<select name=yearmonth size=1>
<?php
$dates = $db->queryAllLists('SELECT year, month FROM history WHERE server_id = %s ORDER BY year ASC, month ASC', $serverID);
foreach($dates as [$hYear, $hMonth]){
$value = "".$hYear.StringUtil::padStringAlignRight($hMonth, 2, "0");
if ($hYear == $year && $hMonth == $month) {
echo "
<option selected value={$value}>{$hYear}년 {$hMonth}월</option>";
} else {
echo "
<option value={$value}>{$hYear}년 {$hMonth}월</option>";
}
}
$history = $db->queryFirstRow('SELECT log,genlog,nation,power,gen,city FROM history WHERE server_id = %s AND year = %i AND month = %i', $serverID, $year, $month);
?>
<select id='yearmonth' name=yearmonth size=1>
<option selected='selected'><?=$year?>년 <?=$month?>월</option>
<option><?=$e_year?>년 12월</option>
</select>
<input type=submit name=btn value='조회하기'>
<input type=submit name=btn value="다음달 ▶▶">
+3 -1
View File
@@ -27,7 +27,7 @@ $userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['turnterm', 'opentime', 'turntime']);
$gameStor->cacheValues(['turnterm', 'opentime', 'turntime','autorun_user']);
$connect=$db->get();
increaseRefresh("내정보", 1);
@@ -161,8 +161,10 @@ $('#die_immediately').click(function(){
<input type=<?=$submit?> name=btn style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px; value=설정저장><br>
∞<font color=orange>설정저장은 이달중 <?=$me['myset']?>회 남았습니다.</font><br><br>
</form>
<?php if(!($gameStor->autorun_user['limit_minutes']??false)): ?>
휴 가 신 청<br>
<a href="c_vacation.php"><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>휴가 신청</button></a><br><br>
<?php endif; ?>
<!--빙의 해제용 삭턴 조절<br>
<a href="b_myPage.php?detachNPC=1"><button type="button" style=background-color:<?=GameConst::$basecolor2?>;color:white;width:160px;height:30px;font-size:13px;>빙의 해체 요청</button></a>-->
+9 -3
View File
@@ -87,8 +87,14 @@ jQuery(function($){
$('#form1').submit(function(){
return false;
});
$('.submitBtn').click(function(){
$('#leaveTroop').click(function(e){
return confirm("정말 부대를 탈퇴하시겠습니까?");
})
$('.submitBtn').click(function(event){
if(event.isPropagationStopped()){
return false;
}
console.log('b');
var $this=$(this);
$.post({
@@ -140,7 +146,7 @@ $('.submitBtn').click(function(){
<?php elseif($me['troop'] == 0): ?>
<input type=submit class='submitBtn' value='부 대 가 입'>
<?php else: ?>
<input type=submit class='submitBtn' value='부 대 탈 퇴' onclick='return confirm("정말 부대를 탈퇴하시겠습니까?")'>
<input type=submit id="leaveTroop" class='submitBtn' value='부 대 탈 퇴'>
<?php endif;?>
</td></tr></tfoot>
<tbody>
+27
View File
@@ -106,6 +106,31 @@ if($command == 61) {
die();
}
// 국호변경
if($command == 82) {
$query = "select no,nation,level from general where owner='{$userID}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$me = MYDB_fetch_array($result);
$name = StringUtil::neutralize($name);
if($name == "") { $name = "무명"; }
$db->update('general', [
'makenation'=>$name
], 'owner=%i', $userID);
$count = count($turn);
$str = "type=type";
for($i=0; $i < $count; $i++) {
$str .= ",l{$me['level']}turn{$turn[$i]}='{$comStr}'";
}
$query = "update nation set {$str} where nation='{$me['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
header('location:b_chiefcenter.php', true, 303);
die();
}
//포상, 몰수, 발령, 항복권고, 원조
//선전포고, 종전, 파기, 초토화, 천도, 증축, 감축
//백성동원, 수몰, 허보, 피장파장, 의병모집, 이호경식, 급습
@@ -130,6 +155,8 @@ if($command == 23 || $command == 24 || $command == 27 || $command == 51 || $comm
die();
}
//일반 턴
$query = [];
foreach($turn as $turnIdx){
+6
View File
@@ -10,6 +10,12 @@ $userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$autorun_user = $gameStor->autorun_user;
if($autorun_user['limit_minutes']??false){
//자동 턴인 경우에는 휴가 불가
header('location:b_myPage.php', true, 303);
}
$killturn = $gameStor->killturn;
$db->update('general', [
+11
View File
@@ -192,10 +192,21 @@ div.bar_out div.bar_in{
font-family: '맑은 고딕';
}
.tooltip_copyable_info .tooltiptext{
display: inline;
color: rgba(0,0,0,0);
font-size: 0;
}
.tooltiptext {
display: none;
}
.hidden_but_copyable{
color: rgba(0,0,0,0);
font-size: 0;
}
.btn-group-xs > .btn, .btn-xs {
padding : .25rem .4rem;
font-size : .875rem;
+94 -8
View File
@@ -271,6 +271,11 @@ function myNationInfo() {
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$nation = MYDB_fetch_array($result);
if(!$nation){
$nation = getNationStaticInfo(0);
$nation['tech'] = 0;
}
$query = "select COUNT(*) as cnt, SUM(pop) as totpop, SUM(pop2) as maxpop from city where nation='{$nation['nation']}'"; // 도시 이름 목록
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = MYDB_fetch_array($result);
@@ -341,6 +346,7 @@ function myNationInfo() {
$techCall = getTechCall($nation['tech']);
if(TechLimit($admin['startyear'], $admin['year'], $nation['tech'])) { $nation['tech'] = "<font color=magenta>{$nation['tech']}</font>"; }
else { $nation['tech'] = "<font color=limegreen>{$nation['tech']}</font>"; }
@@ -657,6 +663,8 @@ function commandTable() {
}
commandGroup("", 1);
commandGroup("======= 개 인 ========");
addCommand("내정 특기 초기화(3턴, 1회만)", 38);
addCommand("전투 특기 초기화(3턴, 1회만)", 39);
if($me['level'] >= 1) {
addCommand("단련(자금$develcost, 군량$develcost)", 41);
addCommand("숙련전환(통솔경험, 자금$develcost, 군량$develcost)", 58);
@@ -751,9 +759,10 @@ function CoreCommandTable() {
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$me = MYDB_fetch_array($result);
$query = "select level,can_change_flag from nation where nation='{$me['nation']}'";
$query = "select level,can_change_flag,aux from nation where nation='{$me['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$nation = MYDB_fetch_array($result);
$nationAux = Json::decode($nation['aux']);
$query = "select no from general where nation='{$me['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
@@ -794,7 +803,7 @@ function CoreCommandTable() {
commandGroup("====== 특 수 ======");
addCommand("초토화", 65, $valid);
addCommand("천도/3턴(금쌀{$develcost}0)", 66, $valid);
$cost = $develcost * 500 + 60000; // 7만~13만
$cost = $develcost * GameConst::$expandCityCostCoef + GameConst::$expandCityDefaultCost; // 7만~13만
addCommand("증축/6턴(금쌀{$cost})", 67, $valid);
addCommand("감축/6턴", 68, $valid);
commandGroup("", 1);
@@ -823,6 +832,12 @@ function CoreCommandTable() {
} else {
addCommand("국기 변경", 81, 0);
}
if($nation['level']==7 && !($nationAux['used_82']??0)){
addCommand("국호 변경", 82, 1);
}
else{
addCommand("국호 변경", 82, 0);
}
commandGroup("", 1);
echo "
</select>
@@ -1596,6 +1611,7 @@ function checkTurn() {
CheckOverhead();
//서버정보
$autorun_user = $gameStor->autorun_user;
// 최종 처리 월턴의 다음 월턴시간 구함
$prevTurn = cutTurn($gameStor->turntime, $gameStor->turnterm);
@@ -1614,12 +1630,15 @@ function checkTurn() {
//if(PROCESS_LOG) $processlog[0] = "[{$date}] 월턴 이전 갱신: name({$general['name']}), no({$general['no']}), turntime({$general['turntime']}), turn0({$general['turn0']})";
//if(PROCESS_LOG) pushProcessLog($processlog);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', processAI');
if($general['npc'] >= 2) { processAI($general['no']); } // npc AI 처리
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', PreprocessCommand');
PreprocessCommand($general['no']);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', processAI');
$reduce_turn = false;
if($general['npc'] >= 2 || ($autorun_user['limit_minutes']??false)) {
processAI($general['no'], $reduce_turn);
} // npc AI 처리
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', processCommand');
processCommand($general['no']);
processCommand($general['no'], $reduce_turn);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', updateCommand');
updateCommand($general['no']);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', updateTurntime');
@@ -1731,12 +1750,14 @@ function checkTurn() {
//if(PROCESS_LOG) $processlog[0] = "[{$date}] 월턴 이후 갱신: name({$general['name']}), no({$general['no']}), turntime({$general['turntime']}), turn0({$general['turn0']})";
//if(PROCESS_LOG) pushProcessLog($processlog);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', processAI');
if($general['npc'] >= 2) { processAI($general['no']); } // npc AI 처리
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', PreprocessCommand');
PreprocessCommand($general['no']);
$reduce_turn = false;
if($general['npc'] >= 2 || ($autorun_user['limit_minutes']??false)) {
processAI($general['no'], $reduce_turn);
}
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', processCommand');
processCommand($general['no']);
processCommand($general['no'], $reduce_turn);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', updateCommand');
updateCommand($general['no']);
//if(STEP_LOG) pushStepLog(date('Y-m-d H:i:s').', updateTurntime');
@@ -2780,6 +2801,71 @@ function searchDistance(int $from, int $maxDist=99, bool $distForm = false) {
}
}
/**
* $from 으로 지정한 도시의 인접 도시와 $to 도시의 최단 거리를 계산해 줌
* @param $from 기준 도시 코드
* @param $to 대상 도시 코드
* @param $linkNationList 경로에 해당하는 국가 리스트
* @return array $dist=>[cityID, $nation] 배열 가장 앞이 가장 가까움
*/
function searchDistanceListToDest(int $from, int $to, array $linkNationList) {
$queue = new \SplQueue();
$cities = [];
$db = DB::db();
//TODO: 도시-국가 캐싱이 있으면 쓸모 있지 않을까
$allowedCityList = [];
foreach($db->queryAllLists(
'SELECT city, nation FROM city WHERE nation IN %li',
$linkNationList
) as [$cityID, $nationID]){
$allowedCityList[$cityID] = $nationID;
}
$remainFromCities = [];
foreach(array_keys(CityConst::byID($from)->path) as $fromCityID){
if(key_exists($fromCityID, $allowedCityList)){
$remainFromCities[$fromCityID] = true;
}
}
if(!key_exists($to, $allowedCityList)){
return [];
}
$result = [];
$queue->enqueue([$to, 0]);
while(!empty($remainFromCities) && !$queue->isEmpty()){
list($cityID, $dist) = $queue->dequeue();
if(key_exists($cityID, $cities)){
continue;
}
$cities[$cityID] = $dist;
if(key_exists($cityID, $remainFromCities)){
unset($remainFromCities[$cityID]);
$result[$dist][] = [$cityID, $allowedCityList[$cityID]];
}
foreach(array_keys(CityConst::byID($cityID)->path) as $connCityID){
if($allowedCityList !== null && !key_exists($connCityID, $allowedCityList)){
continue;
}
if(key_exists($connCityID, $cities)){
continue;
}
$queue->enqueue([$connCityID, $dist+1]);
}
}
return $result;
}
function isNeighbor(int $nation1, int $nation2, bool $includeNoSupply=true) {
if($nation1 === $nation2){
return false;
+19 -3
View File
@@ -170,6 +170,13 @@ function getTurn(array $general, $type, $font=1) {
$str[$i] = "{$city['name']}】에 선동 실행";
break;
case 38: //내특 초기화
$str[$i] = "내정 특기를 초기화";
break;
case 39: //전특 초기화
$str[$i] = "전투 특기를 초기화";
break;
case 41: //단련
$str[$i] = "숙련도를 단련";
break;
@@ -469,6 +476,9 @@ function getCoreTurn($nation, $level) {
$str[$i] = "【<font color={$color}>국기</font>】를 변경";
break;
case 82: //국호변경
$str[$i] = "국호를 변경";
break;
default:
$str[$i] = "????";
break;
@@ -483,13 +493,13 @@ function getCoreTurn($nation, $level) {
}
function processCommand($no) {
function processCommand($no, $reduceTurn) {
$session = Session::getInstance();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$general = $db->queryFirstRow('SELECT npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar,myset from general where no = %i', $no);
$general = $db->queryFirstRow('SELECT npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar,myset,aux from general where no = %i', $no);
list($month, $killturn) = $gameStor->getValuesAsArray(['month', 'killturn']);
$log = [];
@@ -545,11 +555,12 @@ function processCommand($no) {
case 77: process_77($general); break; //이호경식
case 78: process_78($general); break; //급습
case 81: process_81($general); break; //국기변경
case 82: process_82($general); break; //국호변경
case 99: break; //수뇌부휴식
}
//장수정보 재로드
$query = "select npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar,myset from general where no='$no'";
$query = "select npc,no,name,picture,imgsvr,nation,nations,city,troop,injury,affinity,leader,leader2,power,power2,intel,intel2,experience,dedication,level,gold,rice,crew,crewtype,train,atmos,weap,book,horse,item,turntime,makenation,makelimit,killturn,block,dedlevel,explevel,age,belong,personal,special,special2,term,turn0,dex0,dex10,dex20,dex30,dex40,warnum,killnum,deathnum,killcrew,deathcrew,recwar,myset,aux from general where no='$no'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$general = MYDB_fetch_array($result);
}
@@ -561,6 +572,8 @@ function processCommand($no) {
$newKillturn = $general['killturn'] - 1;
} elseif($command[0] == 0) {
$newKillturn = $general['killturn'] - 1;
} elseif($reduceTurn == true){
$newKillturn = $general['killturn'] - 1;
} else {
$newKillturn = $killturn;
}
@@ -619,6 +632,9 @@ function processCommand($no) {
case 34: process_34($general); break; //파괴
case 35: process_35($general); break; //선동
case 38: process_38($general, '내정 특기', 'special', 'specage'); break; //내특 초기화
case 39: process_38($general, '전투 특기', 'special2', 'specage2'); break; //내특 초기화
case 41: process_41($general); break; //단련
case 42: process_42($general); break; //견문
case 43: process_43($general); break; //증여
+2
View File
@@ -1015,6 +1015,7 @@ function updateNationState() {
$josaUl = JosaUtil::pick(getNationLevel($nationlevel), '을');
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>".getNationLevel($nationlevel)."</>{$josaUl} 자칭하였습니다.";
pushNationHistory($nation, "<C>●</>{$admin['year']}{$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>".getNationLevel($nationlevel)."</>{$josaUl} 자칭");
$db->update('nation', ['can_change_flag'=>1], 'nation=%i', $nation['nation']);
break;
case 6:
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>".getNationLevel($nationlevel)."</>에 등극하였습니다.";
@@ -1316,6 +1317,7 @@ function convForOldGeneral(array $general, int $year, int $month){
function storeOldGeneral(int $no, int $year, int $month){
$db = DB::db();
$general = $db->queryFirstRow('SELECT * FROM general WHERE `no` = %i', $no);
$general['aux'] = Json::decode($general['aux']);
if(!$general){
return;
}
+240 -100
View File
@@ -1,6 +1,76 @@
<?php
namespace sammo;
class AIAllowedAction{
public $develop = true;
public $warp = true;
public $recruitLowestCivil = false;
public $randomRecruit = true;
public $recruit = true;
public $recruit_high = false;
public $train = true;
public $atmos = true;
public $battle = true;
public $appointment = true;
public $changeWarCondition = true;
public $donation = true;
public $buySellRice = true;
public $staffAction = true;
function __construct($npc, $aiOptions){
if($npc >= 2){
return;
}
$this->develop = false;
$this->warp = false;
$this->randomRecruit = false;
$this->recruit = false;
$this->recruit_high = false;
$this->train = false;
$this->atmos = false;
$this->battle = false;
$this->appointment = false;
$this->changeWarCondition = false;
$this->donation = false;
$this->buySellRice = true;
$this->staffAction = false;
$this->recruitLowestCivil = true;
foreach($aiOptions as $key=>$value){
assert($value);
switch($key){
case 'develop':
$this->develop = true;
break;
case 'warp':
$this->warp = true;
break;
case 'recruit_high':
$this->recruit_high = true;
case 'recruit':
$this->recruit = true;
break;
case 'train':
$this->train = true;
$this->atmos = true;
break;
case 'battle':
$this->battle = true;
break;
}
}
}
}
function SetDevelop($genType, $no, $city, $tech) {
$db = DB::db();
$connect=$db->get();
@@ -83,7 +153,7 @@ function SetDevelop($genType, $no, $city, $tech) {
return;
}
function SetCrew($no, $nationID, $personal, $gold, $leader, $genType, $tech, $dex0, $dex10, $dex20, $dex30, $dex40) {
function SetCrew($no, $nationID, $personal, $gold, $leader, $genType, $tech, $dex0, $dex10, $dex20, $dex30, $dex40, $currentCrewType, AIAllowedAction $allowedAction) {
$db = DB::db();
$connect=$db->get();
@@ -99,7 +169,6 @@ function SetCrew($no, $nationID, $personal, $gold, $leader, $genType, $tech, $de
[$startyear, $year] = $gameStor->getValuesAsArray(['startyear', 'year']);
$relYear = Util::valueFit($year-$startyear, 0);
$type = 0;
switch($genType) {
case 0: //무장
case 2: //무내정장
@@ -160,7 +229,13 @@ function SetCrew($no, $nationID, $personal, $gold, $leader, $genType, $tech, $de
}
if($types){
$type = Util::choiceRandom($types);
if(!$allowedAction->randomRecruit && in_array($currentCrewType, $types) && ($currentCrewType != GameUnitConst::DEFAULT_CREWTYPE && $currentCrewType != $types[0])){
$type = $currentCrewType;
}
else{
$type = Util::choiceRandom($types);
}
}
else{
$type = GameUnitConst::DEFAULT_CREWTYPE;
@@ -175,19 +250,25 @@ function SetCrew($no, $nationID, $personal, $gold, $leader, $genType, $tech, $de
$crew = intdiv($gold, $cost);
if($leader < $crew) { $crew = $leader; }
$command = EncodeCommand(0, $type, $crew, 11);
if($allowedAction->recruit_high && $crew * $cost * 6 < $gold){
$command = EncodeCommand(0, $type, $crew, 12);
}
else{
$command = EncodeCommand(0, $type, $crew, 11);
}
$query = "update general set turn0='$command' where no='$no'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
return;
}
function processAI($no) {
function processAI($no, &$reduce_turn) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$admin = $gameStor->getValues(['startyear','year','month','turnterm','scenario','gold_rate','rice_rate']);
$admin = $gameStor->getValues(['startyear','year','month','turnterm','scenario','gold_rate','rice_rate','killturn','autorun_user']);
// 초반 여부
if($admin['startyear']+2 > $admin['year'] || ($admin['startyear']+2 == $admin['year'] && $admin['month'] < 5)) {
$isStart = 1;
@@ -195,7 +276,8 @@ function processAI($no) {
$isStart = 0;
}
$query = "select no,turn0,npcid,name,nation,nations,city,level,npcmsg,personal,leader,intel,power,gold,rice,crew,train,atmos,troop,npc,affinity,mode,injury,picture,imgsvr,killturn,makelimit,dex0,dex10,dex20,dex30,dex40 from general where no='$no'";
$query = "select no,turn0,npcid,name,nation,nations,city,level,npcmsg,personal,leader,intel,power,horse,weap,book,item,special,special2,gold,rice,crew,crewtype,train,atmos,troop,npc,affinity,mode,injury,picture,imgsvr,killturn,makelimit,dex0,dex10,dex20,dex30,dex40 from general where no='$no'";
$result = MYDB_query($query, $connect) or Error("processAI01 ".MYDB_error($connect),"");
$general = MYDB_fetch_array($result);
@@ -240,15 +322,58 @@ function processAI($no) {
return;
}
$autorun_user = $admin['autorun_user'];
if($general['npc'] < 2){
$autorun_limit_minutes = $autorun_user['limit_minutes']??0;
if(!$autorun_limit_minutes){
return;
}
if($general['nation'] == 0){
return;
}
$blankTurnCnt = $admin['killturn']-$general['killturn'];
if($blankTurnCnt * $admin['turnterm'] > $autorun_limit_minutes){
return;
}
}
// 입력된 턴이 있으면 그것 실행
if(DecodeCommand($general['turn0'])[0] != 0) {
return;
}
$query = "select city,region,nation,level,path,rate,gen1,gen2,gen3,pop,supply,front from city where city='{$general['city']}'";
$reduce_turn = true;
$allowedAction = new AIAllowedAction($general['npc'], $autorun_user['options']??[]);
if($general['troop'] && $allowedAction->warp){
$troopLeader = $db->queryFirstRow(
'SELECT general.no,general.name,general.city,turn0,troop,general.nation, city.nation AS city_nation FROM general JOIN city ON city.city = general.city WHERE troop = %i', $general['troop']
);
if(!$troopLeader){
//부대장 사망..?
}
else if(DecodeCommand($troopLeader['turn0'])[0] != 26){
//valid
}
else if($troopLeader['nation'] == $troopLeader['city_nation']){
//valid
}
else{
$allowedAction->warp = false;
}
}
$query = "select city,region,nation,level,path,rate,gen1,gen2,gen3,pop,supply,front,trade from city where city='{$general['city']}'";
$result = MYDB_query($query, $connect) or Error("processAI02 ".MYDB_error($connect),"");
$city = MYDB_fetch_array($result);
if ($general['npc'] < 2 && $allowedAction->buySellRice) {
if($city['trade'] == 0){
$allowedAction->buySellRice = false;
}
}
$query = "select nation,level,tech,gold,rice,rate,type,color,name,war from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error("processAI03 ".MYDB_error($connect),"");
$nation = MYDB_fetch_array($result)??[
@@ -261,6 +386,9 @@ function processAI($no) {
'tech'=>0,
];
setLeadershipBonus($general, $nation['level']);
$leadership = getGeneralLeadership($general, false, true, true, true);
$coreCommand = array();
if($general['level'] >= 5) {
$query = "select l{$general['level']}turn0 from nation where nation='{$general['nation']}'";
@@ -327,17 +455,11 @@ function processAI($no) {
$tech = getTechCost($nation['tech']);
$resrc = $tech * 700;//XXX: 왜 700이지?
if($general['atmos'] >= 90 && $general['train'] >= 90) {
if($general['mode'] == 0) {
$query = "update general set mode=1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),"");
}
} else {
if($general['mode'] == 1) {
$query = "update general set mode=0 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),"");
}
if($allowedAction->changeWarCondition && $general['mode'] != 2){
$query = "update general set mode=2 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),"");
}
//운영자메시지 출력 하루 6번..?
//특별 메세지 있는 경우 출력 하루 4번
@@ -369,7 +491,7 @@ function processAI($no) {
$rulerNation = $db->queryFirstField('SELECT nation FROM general WHERE `level`=12 AND npc=9 and nation not in %li ORDER BY RAND() limit 1', Json::decode($general['nations']));
if($ruler) {
if($rulerNation) {
$command = EncodeCommand(0, 0, $rulerNation, 25); //임관
} else {
$command = EncodeCommand(0, 0, 0, 42); //견문
@@ -377,7 +499,7 @@ function processAI($no) {
$query = "update general set turn0='$command' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI07 ".MYDB_error($connect),"");
return;
} elseif($general['npc'] != 9 && $general['level'] == 0) {
} elseif($general['npc'] != 9 && $general['level'] == 0 && $allowedAction->appointment) {
switch(Util::choiceRandomUsingWeight([11.4, 40, 20, 28.6])) {
//임관 10%
case 0:
@@ -432,7 +554,7 @@ function processAI($no) {
$rulerCommand = 0;
//군주가 할일
if($general['level'] == 12) {
if($general['level'] == 12 && $allowedAction->staffAction) {
//오랑캐인데 공격 못하면 바로 방랑/해산
if($general['npc'] == 9 && $dipState == 0 && !$attackable) {
//방랑군이냐 아니냐
@@ -547,7 +669,7 @@ function processAI($no) {
}
//방랑군 아니고, 입력된 턴이 없을때 수뇌부가 할일
if($nation['level'] != 0 && $general['level'] >= 5 && $rulerCommand == 0) {
if($nation['level'] != 0 && $general['level'] >= 5 && $rulerCommand == 0 && $allowedAction->staffAction) {
$command = NPCStaffWork($general, $nation, $dipState);
if($command){
$db->update('nation', [
@@ -569,7 +691,7 @@ function processAI($no) {
} elseif($general['injury'] > 10) {
// 부상 2달 이상이면 요양
$command = EncodeCommand(0, 0, 0, 50); //요양
} elseif($nation['level'] == 0) {
} elseif($nation['level'] == 0 && $allowedAction->appointment) {
//방랑군일때
if($admin['startyear']+3 <= $admin['year']) {
$command = EncodeCommand(0, 0, 0, 45); //하야
@@ -591,7 +713,7 @@ function processAI($no) {
return;
}
if($general['leader'] < 40){
if($general['leader'] < 40 && $allowedAction->donation){
//무지장인데
if(
@@ -626,7 +748,7 @@ function processAI($no) {
}
//국가 병량이 없을때 바로 헌납
if($nation['rice'] < 2000 && $general['rice'] > 200) {
if($nation['rice'] < 2000 && $general['rice'] > 200 && $allowedAction->donation) {
$amount = intdiv($general['rice'] - 200, 100) + 1;
if($amount > 20) { $amount = 20; }
$command = EncodeCommand(0, 2, $amount, 44); //헌납
@@ -646,23 +768,23 @@ function processAI($no) {
$target = array();
// 평시거나 초반아니면서 공격가능 없으면서 병사 있으면 해제(25%)
if($dipState == 0 && $isStart == 0 && !$attackable && $general['crew'] > 0 && rand()% 100 < 25) {
if($allowedAction->recruit && $dipState == 0 && $isStart == 0 && !$attackable && $general['crew'] > 0 && rand()% 100 < 25) {
$command = EncodeCommand(0, 0, 0, 17); //소집해제
} elseif($dipState <= 1 || $isStart == 1) {
//평시이거나 선포있어도 초반이면
if($general['gold'] + $general['rice'] < 200) { $command = EncodeCommand(0, 0, 0, 9); } //금쌀없으면 조달9
elseif($general['rice'] > 100 && $city['rate'] < 95) { $command = EncodeCommand(0, 0, 0, 4); } //우선 선정
elseif($general['gold'] < 100) { //금없으면 쌀팜
elseif($general['rice'] > 100 && $city['rate'] < 95 && $allowedAction->develop) { $command = EncodeCommand(0, 0, 0, 4); } //우선 선정
elseif($general['gold'] < 100 && $allowedAction->buySellRice) { //금없으면 쌀팜
$amount = intdiv(($general['rice'] - $general['gold'])/2, 100); // 100단위
$command = EncodeCommand(0, 1, $amount, 49); //팜
} elseif($general['gold'] < 500 && $general['rice'] < 500) { $command = EncodeCommand(0, 0, 0, 1); } //금쌀되면 내정
elseif($general['rice'] < 100) { //쌀없으면 쌀삼
} elseif($general['gold'] < 500 && $general['rice'] < 500 && $allowedAction->develop) { $command = EncodeCommand(0, 0, 0, 1); } //금쌀되면 내정
elseif($general['rice'] < 100 && $allowedAction->buySellRice) { //쌀없으면 쌀삼
$amount = intdiv(($general['gold'] - $general['rice'])/2, 100); // 100단위
$command = EncodeCommand(0, 2, $amount, 49); //삼
} elseif($genType >= 2) { $command = EncodeCommand(0, 0, 0, 1); } //내정장일때 내정
} elseif($genType >= 2 && $allowedAction->develop) { $command = EncodeCommand(0, 0, 0, 1); } //내정장일때 내정
else {
//현도시가 전방이면 공격 가능성 체크
if($city['front'] > 0) {
if($city['front'] > 0 && $allowedAction->battle) {
//주변도시 체크
$paths = explode('|', $city['path']);
for($i=0; $i < count($paths); $i++) {
@@ -687,6 +809,11 @@ function processAI($no) {
$sel = rand() % 10;
if($selCity['dev'] > 95) { $sel = 9; }
elseif($selCity['dev'] < 70) { $sel = 0; }
if(!$allowedAction->warp){
$sel = 0;
}
switch($sel) {
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: // 그대로 내정 80 %
$command = EncodeCommand(0, 0, 0, 1);
@@ -729,22 +856,22 @@ function processAI($no) {
} else { // 공격인 경우
if($general['crew'] < 1000 && $general['gold'] >= $resrc && $general['rice'] >= $resrc) { //자원되고, 병사없을때
if($city['pop'] > 40000) { $command = EncodeCommand(0, 0, 0, 11); }
if($city['pop'] > 40000 && $allowedAction->recruit) { $command = EncodeCommand(0, 0, 0, 11); }
else { $command = EncodeCommand(0, 0, 0, 1); }
} elseif($general['rice'] < $resrc && $general['rice'] <= $general['gold']) {
} elseif($general['rice'] < $resrc && $general['rice'] <= $general['gold'] && $allowedAction->buySellRice) {
//금이 더 많으면 매매
$amount = intdiv(($general['gold'] - $general['rice']) / 2, 100); // 100단위
if($amount > 0) { $command = EncodeCommand(0, 2, $amount, 49); }//삼
else { $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); } // 내정, 조달
} elseif($general['gold'] < $resrc && $general['rice'] > $general['gold']) {
} elseif($general['gold'] < $resrc && $general['rice'] > $general['gold'] && $allowedAction->buySellRice) {
//쌀이 더 많으면 매매
$amount = intdiv(($general['rice'] - $general['gold']) / 2, 100); // 100단위
if($amount > 0) { $command = EncodeCommand(0, 1, $amount, 49); }//팜
else { $command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); } // 내정, 조달
//자원, 병사 모두 충족
} elseif($general['crew'] >= 1000 && $general['train'] < 90) {
} elseif($general['crew'] >= 1000 && $general['train'] < 90 && $allowedAction->train) {
$command = EncodeCommand(0, 0, 0, 13); //훈련
} elseif($general['crew'] >= 1000 && $general['atmos'] < 90) {
} elseif($general['crew'] >= 1000 && $general['atmos'] < 90 && $allowedAction->atmos) {
$command = EncodeCommand(0, 0, 0, 14); //사기진작
} else {
//공격
@@ -764,18 +891,18 @@ function processAI($no) {
//전시일때
if($general['gold'] + $general['rice'] < $resrc*2) { $command = EncodeCommand(0, 0, 0, 9); } //금쌀없으면 조달
elseif($general['rice'] > $resrc && $city['rate'] < 95 && $city['front'] == 0) { $command = EncodeCommand(0, 0, 0, 4); } // 우선 선정
elseif($general['rice'] > $resrc && $city['rate'] < 50 && $city['front'] > 0) { $command = EncodeCommand(0, 0, 0, 4); } // 우선 선정
elseif($general['gold'] < $resrc || ($general['gold'] < $resrc *2 && $general['rice'] > $resrc * 6)) { // 금없으면 쌀팜
elseif($general['rice'] > $resrc && $city['rate'] < 95 && $city['front'] == 0 && $allowedAction->develop) { $command = EncodeCommand(0, 0, 0, 4); } // 우선 선정
elseif($general['rice'] > $resrc && $city['rate'] < 50 && $city['front'] > 0 && $allowedAction->develop) { $command = EncodeCommand(0, 0, 0, 4); } // 우선 선정
elseif(($general['gold'] < $resrc || ($general['gold'] < $resrc *2 && $general['rice'] > $resrc * 6)) && $allowedAction->buySellRice) { // 금없으면 쌀팜
$amount = intdiv(($general['rice'] - $general['gold'])/2, 100); // 100단위
if($amount > 0) { $command = EncodeCommand(0, 1, $amount, 49); }// 팜
else { $command = EncodeCommand(0, 0, 0, 9); } // 조달
} elseif($general['rice'] < $resrc || ($general['rice'] < $resrc *2 && $general['gold'] > $resrc * 6)) { // 쌀없으면 쌀삼
} elseif(($general['rice'] < $resrc || ($general['rice'] < $resrc *2 && $general['gold'] > $resrc * 6)) && $allowedAction->buySellRice) { // 쌀없으면 쌀삼
$amount = intdiv(($general['gold'] - $general['rice'])/2, 100); // 100단위
if($amount > 0) { $command = EncodeCommand(0, 2, $amount, 49); }// 팜
else { $command = EncodeCommand(0, 0, 0, 9); } // 조달
} elseif($genType >= 2) { $command = EncodeCommand(0, 0, 0, 1); } //내정장일때 내정
elseif($general['crew'] < 1000 && $general['gold'] >= $resrc && $general['rice'] >= $resrc) {
elseif($general['crew'] < 1000 && $general['gold'] >= $resrc && $general['rice'] >= $resrc && $allowedAction->recruit) {
$query = "select no from general where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),"");
$genCount = MYDB_num_rows($result);
@@ -793,38 +920,29 @@ function processAI($no) {
$ratio2 = Util::round($genCount2 / $genCount * 100);
$ratio3 = rand() % 100;
// 전체 인구 대비 확률로 현지에서 징병
if($city['pop'] > 40000 && 100 + $ratio - $ratio2 > $ratio3) {
$minRecruitPop = 30000 + max($allowedAction->recruitLowestCivil?0:20000, $leadership * 100);
if($city['pop'] >= $minRecruitPop && 100 + $ratio - $ratio2 > $ratio3) {
$command = EncodeCommand(0, 0, 0, 11); //인구 되면 징병
} else {
// 인구 안되면 4만 이상인 도시로 워프
$query = "select city from city where nation='{$general['nation']}' and pop>40000 and supply='1' order by rand() limit 0,1";
$result = MYDB_query($query, $connect) or Error("processAI16 ".MYDB_error($connect),"");
$cityCount = MYDB_num_rows($result);
if($cityCount > 0) {
} else{
$warpCityID = $db->queryFirstField('SELECT city FROM city WHERE nation=%i AND pop>=%i AND supply=1 ORDER BY rand() limit 1', $general['nation'], $minRecruitPop);
if($warpCityID && $allowedAction->warp) {
$selCity = MYDB_fetch_array($result);
//워프
$query = "update general set city='{$selCity['city']}' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI18 ".MYDB_error($connect),"");
$db->update('general', [
'city'=>$warpCityID
], 'no=%i', $general['no']);
$command = EncodeCommand(0, 0, 0, 50); //요양
$query = "update general set turn0='$command' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI23 ".MYDB_error($connect),"");
return;
} else {
} else if($allowedAction->develop){
$command = EncodeCommand(0, 0, 0, 7); //인구 안되면 정장
}
}
} elseif($general['crew'] >= 1000 && $general['train'] < 90) {
if($general['atmos'] >= 90 && $general['train'] >= 60 && $general['mode'] == 0) {
$query = "update general set mode=1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),"");
}
} elseif($general['crew'] >= 1000 && $general['train'] < 90 && $allowedAction->train) {
$command = EncodeCommand(0, 0, 0, 13); //훈련
} elseif($general['crew'] >= 1000 && $general['atmos'] < 90) {
if($general['atmos'] >= 60 && $general['train'] >= 90 && $general['mode'] == 0) {
$query = "update general set mode=1 where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI05 ".MYDB_error($connect),"");
}
} elseif($general['crew'] >= 1000 && $general['atmos'] < 90 && $allowedAction->atmos) {
$command = EncodeCommand(0, 0, 0, 14); //사기진작
} elseif($dipState <= 3) {
$command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); // 준비는 됐으나 아직 선포중이면 내정, 조달
@@ -844,32 +962,37 @@ function processAI($no) {
if($dip['state'] == 0) $target[] = $targetCity['city'];
}
}
if(count($target) == 0) {
//전방 도시 선택, 30% 확률로 태수 있는 전방으로 워프
if(rand()%100 < 30) {
$query = "select city from city where nation='{$general['nation']}' and supply='1' and front>0 order by gen1 desc,rand() limit 0,1";
} else {
$query = "select city from city where nation='{$general['nation']}' and supply='1' and front>0 order by rand() limit 0,1";
if(count($target) == 0 && $allowedAction->warp) {
//전방 도시 선택, 태수, 군사, 시중이 배정되어 있으면 이동 확률 증가
$warpCities = $db->queryAllLists('SELECT city, gen1, gen2, gen3 FROM city WHERE nation = %i AND supply = 1 AND front > 0', $general['nation']);
$warpCandidates = [];
foreach($warpCities as [$cityID, $gen1, $gen2, $gen3]){
$score = 1;
if($gen1){
$score += 1;
}
if($gen2){
$score += 1;
}
if($gen3){
$score += 1;
}
$warpCandidates[$cityID] = $score;
}
$result = MYDB_query($query, $connect) or Error("processAI10 ".MYDB_error($connect),"");
$cityCount = MYDB_num_rows($result);
if($cityCount == 0) {
if($warpCandidates){
$selCity = Util::choiceRandomUsingWeight($warpCandidates);
}
else{
//도시 수, 랜덤(상위 20%) 선택, 저개발 도시 선택
$query = "select city from city where nation='{$general['nation']}' and supply='1'";
$result = MYDB_query($query, $connect) or Error("processAI10 ".MYDB_error($connect),"");
$cityCount = MYDB_num_rows($result);
$citySelect = rand() % (Util::round($cityCount/5) + 1);
$cityCnt = $db->queryFirstField('SELECT count(city) FROM city WHERE nation=%i AND supply=1', $general['nation']);
$citySelect = Util::randRangeInt(0, Util::toInt($cityCnt/5));
$query = "select city,(def+wall)/(def2+wall2) as dev from city where nation='{$general['nation']}' and supply='1' order by dev limit {$citySelect},1";
$result = MYDB_query($query, $connect) or Error("processAI10 ".MYDB_error($connect),"");
$selCity = MYDB_fetch_array($result);
} else {
$selCity = MYDB_fetch_array($result);
$selCity = $db->queryFirstField('SELECT city, (def+wall)/(def2+wall2) as dev from city where nation=%i and supply=1 order by dev limit %i,1',$general['nation'], $citySelect);
}
if($general['city'] != $selCity['city']) {
if($general['city'] != $selCity) {
//워프
$query = "update general set city='{$selCity['city']}' where no='{$general['no']}'";
$query = "update general set city='{$selCity}' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error("processAI18 ".MYDB_error($connect),"");
$command = EncodeCommand(0, 0, 0, 50); //요양
@@ -879,20 +1002,36 @@ function processAI($no) {
} else {
$command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); //공격 가능도시가 없고 워프도 안되면 내정, 조달
}
} elseif($nation['war'] == 1) {
} elseif($nation['war'] == 1 || !$allowedAction->battle) {
//전금이면 내정, 조달
$command = EncodeCommand(0, 0, 0, (rand()%2)*8 + 1); //내정, 조달
} else { $command = EncodeCommand(0, 0, $target[rand()%count($target)], 16); } //있으면 공격
} else if($target && $general['crew'] >= 1000){ $command = EncodeCommand(0, 0, $target[rand()%count($target)], 16); } //있으면 공격
}
}
}
switch($command) {
case EncodeCommand(0, 0, 0, 1): //내정
SetDevelop($genType, $general['no'], $general['city'], $nation['tech']);
if($allowedAction->develop){
SetDevelop($genType, $general['no'], $general['city'], $nation['tech']);
}
else{
$db->update('general', [
'turn0'=>EncodeCommand(0, 0, 0, 29)
], 'no=%i', $general['no']);
}
return;
case EncodeCommand(0, 0, 0, 11): //징병
SetCrew($general['no'], $general['nation'], $general['personal'], $general['gold'], $general['leader'], $genType, $nation['tech'], $general['dex0'], $general['dex10'], $general['dex20'], $general['dex30'], $general['dex40']);
if ($allowedAction->recruit) {
SetCrew($general['no'], $general['nation'], $general['personal'], $general['gold'], $leadership, $genType, $nation['tech'], $general['dex0'], $general['dex10'], $general['dex20'], $general['dex30'], $general['dex40'], $general['crewtype'], $allowedAction);
}
else{
$db->update('general', [
'turn0'=>EncodeCommand(0, 0, 0, 29)
], 'no=%i', $general['no']);
}
return;
default:
$query = "update general set turn0='$command' where no='{$general['no']}'";
@@ -911,7 +1050,6 @@ function NPCStaffWork($general, $nation, $dipState){
$nationCities = [];
$frontCitiesID = [];
$frontImportantCitiesID = [];
$supplyCitiesID = [];
$backupCitiesID = [];
@@ -933,10 +1071,18 @@ function NPCStaffWork($general, $nation, $dipState){
if($nationCity['supply']){
$supplyCitiesID[] = $cityID;
if($nationCity['front']){
$frontCitiesID[] = $cityID;
$score = 1;
if($nationCity['gen1']){
$frontImportantCitiesID[] = $cityID;
$score += 1;
}
if($nationCity['gen2']){
$score += 1;
}
if($nationCity['gen3']){
$score += 1;
}
$frontCitiesID[$cityID] = $score;
}
else{
$backupCitiesID[] = $cityID;
@@ -944,7 +1090,6 @@ function NPCStaffWork($general, $nation, $dipState){
}
}
Util::shuffle_assoc($nationCities);
shuffle($frontCitiesID);
shuffle($supplyCitiesID);
$nationGenerals = [];
@@ -1002,7 +1147,7 @@ function NPCStaffWork($general, $nation, $dipState){
$lostGeneral = $nationGenerals[$lostGeneralID];
if($lostGeneral['npc'] < 2){
if($dipState >= 3 && $frontCitiesID){
$selCityID = Util::choiceRandom($frontCitiesID);
$selCityID = Util::choiceRandomUsingWeight($frontCitiesID);
}
else{
$selCityID = Util::choiceRandom($supplyCitiesID);
@@ -1154,7 +1299,7 @@ function NPCStaffWork($general, $nation, $dipState){
continue;
}
if($dipState >= 3 && $frontCitiesID){
$selCityID = Util::choiceRandom($frontCitiesID);
$selCityID = Util::choiceRandomUsingWeight($frontCitiesID);
}
else{
$selCityID = Util::choiceRandom($supplyCitiesID);
@@ -1272,12 +1417,7 @@ function NPCStaffWork($general, $nation, $dipState){
$score *= 4;
}
if(Util::randBool(0.3) && $frontImportantCitiesID){
$targetCityID = Util::choiceRandom($frontImportantCitiesID);
}
else{
$targetCityID = Util::choiceRandom($frontCitiesID);
}
$targetCityID = Util::choiceRandomUsingWeight($frontCitiesID);
$command = EncodeCommand(0, $nationGeneral['no'], $targetCityID, 27);
@@ -1313,7 +1453,7 @@ function NPCStaffWork($general, $nation, $dipState){
if(!$generalCity['front']){
continue;
}
if($generalCity['pop'] - 33000 > $nationGeneral['leader']){
if($generalCity['pop'] - 33000 > $nationGeneral['leader'] * 100){
continue;
}
if($nationGeneral['troop'] != 0){
@@ -1328,7 +1468,7 @@ function NPCStaffWork($general, $nation, $dipState){
$popTrial = 5;
for($popTrial = 0; $popTrial < 5; $popTrial++){
$targetCity = $nationCities[Util::choiceRandom($backupCitiesID)];
if($targetCity['pop'] < 33000 + $nationGeneral['leader']){
if($targetCity['pop'] < 33000 + $nationGeneral['leader'] * 100){
continue;
}
if (Util::randBool($targetCity['pop'] / $targetCity['pop2'])) {
+177 -57
View File
@@ -1273,7 +1273,6 @@ function process_15(&$general) {
function process_16(&$general) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$log = [];
$alllog = [];
@@ -1282,71 +1281,134 @@ function process_16(&$general) {
$admin = $gameStor->getValues(['startyear', 'year', 'month']);
$query = "select nation,war,sabotagelimit,tech from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$nation = MYDB_fetch_array($result);
$query = "select nation,supply from city where city='{$general['city']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = MYDB_fetch_array($result);
$nation = $db->queryFirstRow('SELECT nation,war,sabotagelimit,tech from nation where nation=%i', $general['nation']);
$city = $db->queryFirstRow('SELECT nation,supply from city where city=%i', $general['city']);
$command = DecodeCommand($general['turn0']);
$destination = $command[1];
$finalTarget = $command[1];
$finalDestCityName = CityConst::byID($finalTarget)->name;
$query = "select * from city where city='$destination'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destcity = MYDB_fetch_array($result);
$query = "select nation,sabotagelimit,tech from nation where nation='{$destcity['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$dnation = MYDB_fetch_array($result);
$query = "select state from diplomacy where me='{$general['nation']}' and you='{$destcity['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$dip = MYDB_fetch_array($result);
if(key_exists($destination, CityConst::byID($general['city'])->path)){
$nearCity = true;
}
else{
$nearCity = false;
}
$josaRo = JosaUtil::pick($destcity['name'], '로');
if($admin['year'] < $admin['startyear']+3) {
$log[] = "<C>●</>{$admin['month']}월:현재 초반 제한중입니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
// } elseif($city['supply'] == 0) {
// $log[] = "<C>●</>{$admin['month']}월:고립된 도시입니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif(!$nearCity) {
$log[] = "<C>●</>{$admin['month']}월:인접도시가 아닙니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($general['level'] == 0) {
$log[] = "<C>●</>{$admin['month']}월:재야입니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($general['crew'] <= 0) {
$log[] = "<C>●</>{$admin['month']}월:병사가 없습니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($general['rice'] <= Util::round($general['crew']/100)) {
$log[] = "<C>●</>{$admin['month']}월:군량이 모자랍니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($dip['state'] != 0) {
$log[] = "<C>●</>{$admin['month']}월:교전중인 국가가 아닙니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($general['nation'] != $city['nation']) {
$log[] = "<C>●</>{$admin['month']}월:본국에서만 출병가능합니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($nation['war'] == 1) {
$log[] = "<C>●</>{$admin['month']}월:현재 전쟁 금지입니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
} elseif($general['nation'] == $destcity['nation']) {
$log[] = "<C>●</>{$admin['month']}월:본국입니다. <G><b>{$destcity['name']}</b></>{$josaRo} 출병 실패. <1>$date</>";
$log[] = "<C>●</>{$admin['month']}월:현재 초반 제한중입니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
if($general['level'] == 0) {
$log[] = "<C>●</>{$admin['month']}월:재야입니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
if($general['crew'] <= 0) {
$log[] = "<C>●</>{$admin['month']}월:병사가 없습니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
if($general['rice'] <= Util::round($general['crew']/100)) {
$log[] = "<C>●</>{$admin['month']}월:군량이 모자랍니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
if($nation['war'] == 1) {
$log[] = "<C>●</>{$admin['month']}월:현재 전쟁 금지입니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
if($general['nation'] != $city['nation']) {
$log[] = "<C>●</>{$admin['month']}월:본국에서만 출병가능합니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
if($general['city'] == $finalTarget){
$log[] = "<C>●</>{$admin['month']}월:이미 도착했습니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
$allowedNationList = $db->queryFirstColumn('SELECT you FROM diplomacy WHERE state = 0 AND me = %i', $general['nation']);
$allowedNationList[] = $general['nation'];
$allowedNationList[] = 0;
$distanceList = searchDistanceListToDest($general['city'], $finalTarget, $allowedNationList);
if(!$distanceList){
$log[] = "<C>●</>{$admin['month']}월:경로에 도달할 방법이 없습니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
pushGenLog($general, $log);
return;
}
$candidateCities = [];
$minDist = Util::array_first_key($distanceList);
do {
//1: 최단 거리 도시 중 공격 대상이 있는가 확인
//2: 최단 거리 + 1 도시 중 공격 대상이 있는가 확인
foreach($distanceList as $dist => $distCitiesInfo){
if($dist > $minDist + 1){
break;
}
$currDist = $dist;
foreach($distCitiesInfo as [$distCityID, $distCityNation]){
if($distCityNation !== $general['nation']){
$candidateCities[] = $distCityID;
}
}
if($candidateCities){
break 2;
}
}
//3: 최단 거리 도시 중 아군 도시 선택
foreach($distanceList[$minDist] as [$distCityID, $distCityNation]){
if($distCityNation === $general['nation']){
$candidateCities[] = $distCityID;
}
}
}while(false);
$destCityID = (int)Util::choiceRandom($candidateCities);
$destCity = $db->queryFirstRow('SELECT * FROM city WHERE city = %i', $destCityID);
if($general['nation'] == $destCity['nation']) {
$log[] = "<C>●</>{$admin['month']}월:경로에 적국 도시가 없습니다. <G><b>{$finalDestCityName}</b></> 방향으로 출병 실패. <1>$date</>";
$general['turn0'] = EncodeCommand(0, 0, $destCityID, 26);
pushGenLog($general, $log);
process_21($general);
return;
} else {
// 전쟁 표시
$query = "update city set state=43,term=3 where city='{$destcity['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
// 숙련도 증가
addGenDex($general['no'], GameConst::$maxAtmosByCommand, GameConst::$maxTrainByCommand, $general['crewtype'], Util::round($general['crew']/100));
// 전투 처리
processWar($general, $destcity);
$log = uniqueItem($general, $log);
}
$destCityName = CityConst::byID($destCityID)->name;
if($finalTarget !== $destCityID){
$josaRo = JosaUtil::pick($finalDestCityName, '로');
$josaUl = JosaUtil::pick($destCityName, '을');
if($minDist == $currDist){
$log[] = "<C>●</>{$admin['month']}월:<G><b>{$finalDestCityName}</b></>{$josaRo} 가기 위해 <G><b>{$destCityName}</b></>{$josaUl} 거쳐야 합니다. <1>$date</>";
}
else{
$log[] = "<C>●</>{$admin['month']}월:<G><b>{$finalDestCityName}</b></>{$josaRo} 가는 도중 <G><b>{$destCityName}</b></>{$josaUl} 거치기로 합니다. <1>$date</>";
}
pushGenLog($general, $log);
$log = [];
}
// 전쟁 표시
$db->update('city', [
'state'=>43,
'term'=>3
], 'city = %i', $destCityID);
// 숙련도 증가
addGenDex($general['no'], GameConst::$maxAtmosByCommand, GameConst::$maxTrainByCommand, $general['crewtype'], Util::round($general['crew']/100));
// 전투 처리
processWar($general, $destCity);
$log = uniqueItem($general, $log);
pushGenLog($general, $log);
}
@@ -1796,6 +1858,55 @@ function process_31(&$general) {
pushGenLog($general, $log);
}
function process_38(&$general, string $specName, string $specTypeKey, string $specAgeKey) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$log = [];
$date = substr($general['turntime'],11,5);
$admin = $gameStor->getValues(['year', 'month']);
$genAux = Json::decode($general['aux']);
if($general['term']%100 == 38) {
$term = intdiv($general['term'], 100) + 1;
$code = $term * 100 + 38;
} else {
$term = 1;
$code = 100 + 38;
}
if($genAux['used_38_'.$specTypeKey]??0){
$log[] = "<C>●</>{$admin['month']}월:이미 {$specName}을 초기화했습니다. {$specName} 초기화 실패. <1>$date</>";
}
else if(!$general[$specTypeKey]) {
$log[] = "<C>●</>{$admin['month']}월:{$specName}를 갖고 있지 않습니다. {$specName} 초기화 실패. <1>$date</>";
} elseif($term < 3) {
$log[] = "<C>●</>{$admin['month']}월:새로운 적성을 찾는 중... ({$term}/3) <1>$date</>";
$query = "update general set resturn='ONGOING',term={$code} where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
} else {
$genAux['used_38_'.$specTypeKey] = 1;
$general[$specAgeKey]=20;
$db->update('general', [
'resturn'=>'SUCCESS',
'term'=>0,
$specTypeKey=>0,
$specAgeKey=>$db->sqleval('age+1'),
'aux'=>Json::encode($genAux)
], 'no = %i', $general['no']);
$log[] = "<C>●</>{$admin['month']}월:새로운 {$specName}를 가질 준비가 되었습니다. <1>$date</>";
}
pushGenLog($general, $log);
}
function process_41(&$general) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -2565,9 +2676,18 @@ function process_58(&$general) {
$cutDex = Util::toInt($fromOrigDex * 0.3);
$fromNewDex = $fromOrigDex - $cutDex;
if($fromDexIdx == $toDexIdx){
$toOrigDex = $fromNewDex;
}
$addDex = Util::toInt($cutDex * 2 / 3);
$toNewDex = $toOrigDex + $addDex;
if($fromDexIdx == $toDexIdx){
$fromNewDex = $toNewDex;
}
$exp = 10;
$exp = CharExperience($exp, $general['personal']);
+116 -16
View File
@@ -1078,7 +1078,7 @@ function process_67(&$general) {
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destcity = MYDB_fetch_array($result);
$amount = $admin['develcost'] * 500 + 60000; // 7만~13만
$amount = $admin['develcost'] * GameConst::$expandCityCostCoef + GameConst::$expandCityDefaultCost; // 7만~13만
$code = $nation["l{$general['level']}term"];
if($code%100 == 67) {
@@ -1131,8 +1131,16 @@ function process_67(&$general) {
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
//수도 증축
$query = "update city set upgrading=upgrading+1,level=level+1,pop2=pop2+100000,agri2=agri2+2000,comm2=comm2+2000,def2=def2+2000,wall2=wall2+2000,secu2=secu2+2000 where city='{$destcity['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$db->update('city', [
'upgrading'=>$db->sqleval('upgrading+1'),
'level'=>$db->sqleval('level+1'),
'pop2'=>$db->sqleval('pop2 + %i', GameConst::$expandCityPopIncreaseAmount),
'agri2'=>$db->sqleval('agri2 + %i', GameConst::$expandCityDevelIncreaseAmount),
'comm2'=>$db->sqleval('comm2 + %i', GameConst::$expandCityDevelIncreaseAmount),
'secu2'=>$db->sqleval('secu2 + %i', GameConst::$expandCityDevelIncreaseAmount),
'def2'=>$db->sqleval('def2 + %i', GameConst::$expandCityWallIncreaseAmount),
'wall2'=>$db->sqleval('wall2 + %i', GameConst::$expandCityWallIncreaseAmount),
], 'city=%i', $destcity['city']);
//경험치, 공헌치
$query = "update general set dedication=dedication+'$ded',experience=experience+'$exp' where no='{$general['no']}'";
@@ -1172,7 +1180,7 @@ function process_68(&$general) {
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$destcity = MYDB_fetch_array($result);
$amount = $admin['develcost'] * 500 + 30000; // 4만~10만
$amount = $admin['develcost'] * GameConst::$expandCityCostCoef + GameConst::$expandCityDefaultCost / 2; // 4만~10만
$code = $nation["l{$general['level']}term"];
if($code%100 == 68) {
@@ -1187,12 +1195,10 @@ function process_68(&$general) {
$log[] = "<C>●</>{$admin['month']}월:수도에서 실행해야 합니다. 감축 실패. <1>$date</>";
} elseif($nation['capital'] != $destcity['city']) {
$log[] = "<C>●</>{$admin['month']}월:수도만 가능합니다. 감축 실패. <1>$date</>";
} elseif($destcity['level'] <= 3) {
$log[] = "<C>●</>{$admin['month']}월:수진, 진, 관문은 불가능합니다. 감축 실패. <1>$date</>";
} elseif($destcity['level'] <= 6) {
$log[] = "<C>●</>{$admin['month']}월:더이상 감축할 수 없습니다. 감축 실패. <1>$date</>";
} elseif($destcity['upgrading'] <= 0) {
$log[] = "<C>●</>{$admin['month']}월:증축된 도시가 아닙니다. 감축 실패. <1>$date</>";
} elseif($destcity['level'] <= 4) {
$log[] = "<C>●</>{$admin['month']}월:수, 진, 관문, 이성은 불가능합니다. 감축 실패. <1>$date</>";
} elseif($general['level'] < 5) {
$log[] = "<C>●</>{$admin['month']}월:수뇌부가 아닙니다. 감축 실패. <1>$date</>";
} elseif($nation['capset'] == 1) {
@@ -1224,12 +1230,12 @@ function process_68(&$general) {
$query = "update nation set l{$general['level']}term='0',capset='1',gold=gold+'$amount',rice=rice+'$amount' where nation='{$general['nation']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$pop = $destcity['pop'] - 100000;
$agri = $destcity['agri'] - 2000;
$comm = $destcity['comm'] - 2000;
$def = $destcity['def'] - 2000;
$wall = $destcity['wall'] - 2000;
$secu = $destcity['secu'] - 2000;
$pop = $destcity['pop'] - GameConst::$expandCityPopIncreaseAmount;
$agri = $destcity['agri'] - GameConst::$expandCityDevelIncreaseAmount;
$comm = $destcity['comm'] - GameConst::$expandCityDevelIncreaseAmount;
$def = $destcity['def'] - GameConst::$expandCityWallIncreaseAmount;
$wall = $destcity['wall'] - GameConst::$expandCityWallIncreaseAmount;
$secu = $destcity['secu'] - GameConst::$expandCityDevelIncreaseAmount;
if($pop < 30000) { $pop = 30000; }
if($agri < 0) { $agri = 0; }
if($comm < 0) { $comm = 0; }
@@ -1237,8 +1243,22 @@ function process_68(&$general) {
if($wall < 0) { $wall = 0; }
if($secu < 0) { $secu = 0; }
//수도 감축
$query = "update city set upgrading=upgrading-1,level=level-1,pop2=pop2-100000,agri2=agri2-2000,comm2=comm2-2000,def2=def2-2000,wall2=wall2-2000,secu2=secu2-2000,pop='$pop',agri='$agri',comm='$comm',def='$def',wall='$wall',secu='$secu' where city='{$destcity['city']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$db->update('city', [
'upgrading'=>$db->sqleval('upgrading-1'),
'level'=>$db->sqleval('level-1'),
'pop2'=>$db->sqleval('pop2 - %i', GameConst::$expandCityPopIncreaseAmount),
'agri2'=>$db->sqleval('agri2 - %i', GameConst::$expandCityDevelIncreaseAmount),
'comm2'=>$db->sqleval('comm2 - %i', GameConst::$expandCityDevelIncreaseAmount),
'secu2'=>$db->sqleval('secu2 - %i', GameConst::$expandCityDevelIncreaseAmount),
'def2'=>$db->sqleval('def2 - %i', GameConst::$expandCityWallIncreaseAmount),
'wall2'=>$db->sqleval('wall2 - %i', GameConst::$expandCityWallIncreaseAmount),
'pop'=>$pop,
'agri'=>$agri,
'comm'=>$comm,
'secu'=>$secu,
'def'=>$def,
'wall'=>$wall
], 'city=%i', $destcity['city']);
//경험치, 공헌치
$query = "update general set dedication=dedication+'$ded',experience=experience+'$exp' where no='{$general['no']}'";
@@ -2457,3 +2477,83 @@ function process_81(&$general) {
pushGeneralPublicRecord($alllog, $admin['year'], $admin['month']);
pushGenLog($general, $log);
}
function process_82(&$general) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$log = [];
$alllog = [];
$history = [];
$date = substr($general['turntime'],11,5);
$admin = $gameStor->getValues(['year','month']);
$query = "select nation from city where city='{$general['city']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$city = MYDB_fetch_array($result);
$query = "select nation,name,type,sabotagelimit,aux from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$nation = MYDB_fetch_array($result);
$nationAux = Json::decode($nation['aux']??'{}');
$newNationName = $general['makenation'];
$nationExists = $db->queryFirstField('SELECT nation FROM nation WHERE name = %s', $newNationName);
if($nationExists){
$log[] = "<C>●</>{$admin['month']}월:이미 같은 국호를 가진 곳이 있습니다. 국호변경 실패. <1>$date</>";
}
else if($city['nation'] != $general['nation']) {
$log[] = "<C>●</>{$admin['month']}월:아국이 아닙니다. 국호변경 실패. <1>$date</>";
} elseif($general['level'] < 5) {
$log[] = "<C>●</>{$admin['month']}월:수뇌부가 아닙니다. 국호변경 실패. <1>$date</>";
} elseif($nationAux['used_82']??0) {
$log[] = "<C>●</>{$admin['month']}월:더이상 변경이 불가능합니다. 국호변경 실패. <1>$date</>";
} else {
$josaRo = JosaUtil::pick($newNationName, '로');
$log[] = "<C>●</>{$admin['month']}월:국호를 <D><b>{$newNationName}{$josaRo}</b></> 변경합니다. <1>$date</>";
$exp = 10;
$ded = 10;
// 성격 보정
$exp = CharExperience($exp, $general['personal']);
$ded = CharDedication($ded, $general['personal']);
$josaYi = JosaUtil::pick($general['name'], '이');
$josaYiNation = JosaUtil::pick($nation['name'], '이');
$query = "select no,name from general where nation='{$general['nation']}' and no!='{$general['no']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$cnt = MYDB_num_rows($result);
$genlog = ["<C>●</><Y>{$general['name']}</>{$josaYi} 국호를 <D><b>{$newNationName}</b></>{$josaRo} 변경합니다."];
for($i=0; $i < $cnt; $i++) {
$gen = MYDB_fetch_array($result);
pushGenLog($gen, $genlog);
}
$alllog[] = "<C>●</>{$admin['month']}월:<Y>{$general['name']}</>{$josaYi} 국호를 <D><b>{$newNationName}</b></>{$josaRo} 변경합니다.";
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<L><b>【국호변경】</b></><D><b>{$nation['name']}</b></>{$josaYiNation} 국호를 <D><b>{$newNationName}</b></>{$josaRo} 변경합니다.";
pushGeneralHistory($general, "<C>●</>{$admin['year']}{$admin['month']}월:국호를 <D><b>{$newNationName}</b></>{$josaRo} 변경");
pushNationHistory($nation, "<C>●</>{$admin['year']}{$admin['month']}월:<Y>{$general['name']}</>{$josaYi} 국호를 <D><b>{$newNationName}</b></>{$josaRo} 변경");
$nationAux['used_82'] = 1;
//국기변경
$db->update('nation', [
'name'=>$newNationName,
'aux'=>Json::encode($nationAux)
], 'nation=%i', $nation['nation']);
//경험치, 공헌치
$query = "update general set dedication=dedication+'$ded',experience=experience+'$exp' where no='{$general['no']}'";
MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
refreshNationStaticInfo();
}
pushWorldHistory($history, $admin['year'], $admin['month']);
pushGeneralPublicRecord($alllog, $admin['year'], $admin['month']);
pushGenLog($general, $log);
}
+16 -3
View File
@@ -199,7 +199,7 @@ function process_25(&$general) {
if($type >= 98 && $genLimit == GameConst::$initialNationGenLimitForRandInit){
//랜덤 모드, 초기화시에는 랜덤 임관을 대신 한턴 더 넣어준다.
$db->update('general', [
'turn1'=>EncodeCommand(0, 0, $type, 25),
'turn1'=>EncodeCommand(0, $type, 0, 25),
], '`no` = %i', $general['no']);
pushGenLog($general, $log);
process_42($general);
@@ -1075,7 +1075,7 @@ function process_57(&$general) {
$history = [];
$date = substr($general['turntime'],11,5);
$admin = $gameStor->getValues(['year', 'month', 'killturn']);
$admin = $gameStor->getValues(['year', 'month', 'killturn', 'autorun_user', 'turn_term']);
$query = "select nation,name from nation where nation='{$general['nation']}'";
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
@@ -1089,6 +1089,19 @@ function process_57(&$general) {
$result = MYDB_query($query, $connect) or Error(__LINE__.MYDB_error($connect),"");
$ruler = MYDB_fetch_array($result);
$killTurnLimit = $admin['killturn'];
$autorunLimit = $admin['autorun_user']['limit_minutes']??0;
if($autorunLimit){
$autorunLimit /= $admin['turn_term'];
if($autorunLimit < GameConst::$maxTurn){
$killTurnLimit -= $autorunLimit;
}
else{
$killTurnLimit -= Util::toInt(sqrt(GameConst::$maxTurn * $autorunLimit));
}
}
if($general['level'] == 0) {
$log[] = "<C>●</>{$admin['month']}월:재야 입니다. 모반 실패. <1>$date</>";
} elseif($general['level'] < 5) {
@@ -1099,7 +1112,7 @@ function process_57(&$general) {
$log[] = "<C>●</>{$admin['month']}월:고립된 도시입니다. 모반 실패. <1>$date</>";
} elseif($general['level'] == 12) {
$log[] = "<C>●</>{$admin['month']}월:이미 군주 입니다. 모반 실패. <1>$date</>";
} elseif($ruler['killturn'] >= $admin['killturn']) {
} elseif($ruler['killturn'] >= $killTurnLimit) {
$log[] = "<C>●</>{$admin['month']}월:군주가 활동중입니다. 모반 실패. <1>$date</>";
} elseif($ruler['npc'] >= 2) {
$log[] = "<C>●</>{$admin['month']}월:군주가 NPC입니다. 모반 실패. <1>$date</>";
+1 -1
View File
@@ -178,7 +178,7 @@ function popIncrease() {
$ratio *= (1 - $city['secu']/$city['secu2']/10); //치안에 따라 최대 10% 경감
}
$pop = $city['pop'] + (int)($city['pop'] * $ratio) + 5000; // 기본 5000명은 증가
$pop = $city['pop'] + (int)($city['pop'] * $ratio) + GameConst::$basePopIncreaseAmount; // 기본인구는 증가
$ratio = round($ratio*100, 2);
$cityrate = $city['rate'];
+1 -1
View File
@@ -304,7 +304,7 @@ else if($session->userGrade == 4){
</select>
<input type="textarea" id="msg_input" maxlength="99">
<input type="textarea" id="msg_input" maxlength="99" value="">
<button id="msg_submit">서신전달&amp;갱신</button><br>
내용 없이 '서신전달&amp;갱신'을 누르면 메세지창이 갱신됩니다.
</div>
+95
View File
@@ -152,6 +152,101 @@ if($session->userGrade < 5 && !$allowReset){
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">휴식 턴 시 장수 턴</label>
<div class="col-sm-9">
<div class="input-group">
<div class="input-group-prepend btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary">
<input type="checkbox" class="autorun_user_chk" data-key="develop" name="autorun_develop" id="autorun_develop">내정
</label>
<label class="btn btn-secondary">
<input type="checkbox" class="autorun_user_chk" data-key="warp" name="autorun_warp" id="autorun_warp">순간이동
</label>
<label class="btn btn-secondary">
<input type="checkbox" class="autorun_user_chk" data-key="recruit" name="autorun_recruit" id="autorun_recruit">징병
</label>
<label class="btn btn-secondary">
<input type="checkbox" class="autorun_user_chk" data-key="recruit_high" name="autorun_recruit_high" id="autorun_recruit_high">모병
</label>
<label class="btn btn-secondary">
<input type="checkbox" class="autorun_user_chk" data-key="train" name="autorun_train" id="autorun_train">훈사
</label>
<label class="btn btn-secondary">
<input type="checkbox" class="autorun_user_chk" data-key="battle" name="autorun_battle" id="autorun_battle">출병
</label>
</div>
<div class="input-group-append">
<span class="input-group-text">유효 시간</span>
</div>
<select class="custom-select" name="autorun_user_minutes" id="autorun_user_minutes">
<option value="0" selected>꺼짐</option>
<option value="43200">항상</option>
<option value="10">10분</option>
<option value="20">20분</option>
<option value="30">30분</option>
<option value="60">1시간</option>
<option value="120">2시간</option>
<option value="180">3시간</option>
<option value="240">4시간</option>
<option value="360">6시간</option>
<option value="480">8시간</option>
<option value="600">10시간</option>
<option value="720">12시간</option>
<option value="1440">24시간</option>
<option value="2160">36시간</option>
<option value="2880">48시간</option>
<option value="3600">60시간</option>
<option value="4320">72시간</option>
</select>
</div>
</div>
</div>
<!--
<div class="form-group row">
<label class="col-sm-3 col-form-label">휴식 턴 시 사령 턴</label>
<div class="col-sm-9">
<div class="input-group">
<div class="input-group-prepend btn-group btn-group-toggle" data-toggle="buttons">
<label class="btn btn-secondary">
<input type="radio" name="autorun_chief_reward" id="autorun_chief_reward">포상/몰수
</label>
<label class="btn btn-secondary">
<input type="radio" name="autorun_chief_warp" id="autorun_chief_warp">발령
</label>
<label class="btn btn-secondary">
<input type="radio" name="autorun_chief_declaration" id="autorun_chief_declaration">선포
</label>
</div>
<div class="input-group-append">
<span class="input-group-text">유효 시간</span>
</div>
<select class="custom-select" name="autorun_chief_minutes" id="autorun_chief_minutes">
<option value="0" selected>꺼짐</option>
<option value="43200">항상</option>
<option value="10">10분</option>
<option value="20">20분</option>
<option value="30">30분</option>
<option value="60">1시간</option>
<option value="120">2시간</option>
<option value="180">3시간</option>
<option value="240">4시간</option>
<option value="360">6시간</option>
<option value="480">8시간</option>
<option value="600">10시간</option>
<option value="720">12시간</option>
<option value="1440">24시간</option>
<option value="2160">36시간</option>
<option value="2880">48시간</option>
<option value="3600">60시간</option>
<option value="4320">72시간</option>
</select>
</div>
</div>
</div>
-->
<div class="form-group row">
<label for="join_mode" class="col-sm-3 col-form-label">임관 모드</label>
<div class="col-sm-9">
+2 -1
View File
@@ -89,7 +89,8 @@ $result = ResetHelper::buildScenario(
$options['show_img_level'],
$options['tournament_trig'],
$options['join_mode'],
$options['starttime']
$options['starttime'],
$options['autorun_user']?:null
);
$result['affected']=1;
+30 -2
View File
@@ -57,7 +57,8 @@ $v->rule('required', [
'extend',
'join_mode',
'npcmode',
'show_img_level'
'show_img_level',
'autorun_user_minutes'
])->rule('integer', [
'turnterm',
'sync',
@@ -67,6 +68,7 @@ $v->rule('required', [
'npcmode',
'show_img_level',
'tournament_trig',
'autorun_user_minutes'
])->rule('in', 'join_mode', ['onlyRandom', 'full']);
if(!$v->validate()){
Json::die([
@@ -108,6 +110,30 @@ $npcmode = (int)$_POST['npcmode'];
$show_img_level = (int)$_POST['show_img_level'];
$tournament_trig = (int)$_POST['tournament_trig'];
$join_mode = $_POST['join_mode'];
$autorun_user_minutes = (int)$_POST['autorun_user_minutes'];
$autorun_user_options = [];
foreach(Util::getReq('autorun_user', 'array_string', []) as $autorun_option){
$autorun_user_options[$autorun_option] = 1;
}
if($autorun_user_minutes > 0 && !$autorun_user_options){
Json::die([
'result'=>false,
'reason'=>'적어도 자동 행동 중 하나는 선택을 해야합니다.'
]);
}
if($autorun_user_minutes < 0){
Json::die([
'result'=>false,
'reason'=>'자동 행동 기한이 0보다 작을 수 없습니다.'
]);
}
$autorun_user = $autorun_user_minutes?[
'limit_minutes'=>$autorun_user_minutes,
'options'=>$autorun_user_options
]:null;
if($reserve_open){
$reserve_open = new \DateTime($reserve_open);
@@ -143,6 +169,7 @@ if($reserve_open){
'gameConf'=>$scenarioObj->getGameConf(),
'join_mode'=>$join_mode,
'starttime'=>$open_date,
'autorun_user'=>$autorun_user
];
@@ -175,5 +202,6 @@ Json::die(ResetHelper::buildScenario(
$show_img_level,
$tournament_trig,
$join_mode,
TimeUtil::DatetimeNow()
TimeUtil::DatetimeNow(),
$autorun_user
));
+4
View File
@@ -82,6 +82,9 @@ switch($commandtype) {
// case 34: command_34($turn, 34); break; //파괴
// case 35: command_35($turn, 35); break; //선동
case 38: command_Single($turn, 38); break; //내특 초기화
case 39: command_Single($turn, 39); break; //전특 초기화
case 41: command_Single($turn, 41); break; //단련
case 42: command_Single($turn, 42); break; //견문
// case 43: command_43( $turn, 43); break; //증여
@@ -121,6 +124,7 @@ switch($commandtype) {
// case 78: command_78($turn, 78); break; //급습
// case 81: command_81($turn, 81); break; //국기변경
// case 82: command_82($turn, 82); break; //국호변경
// case 99: command_99($turn); break; //수뇌부 후식
default: command_Other($turn, $commandtype); break;
+18 -7
View File
@@ -22,6 +22,13 @@ $rootDB = RootDB::db();
$oNow = new \DateTimeImmutable();
$now = $oNow->format('Y-m-d H:i:s');
list(
$year,
$month,
$maxgeneral,
$npcmode
) = $gameStor->getValuesAsArray(['year', 'month', 'maxgeneral', 'npcmode']);
$userNick = RootDB::db()->queryFirstField('SELECT `NAME` FROM member WHERE `NO`=%i',$userID);
if(!$userNick){
Json::die([
@@ -30,6 +37,8 @@ if(!$userNick){
]);
}
$db->query("lock tables general write, select_npc_token write");
$pickResult = $db->queryFirstField('SELECT pick_result FROM select_npc_token WHERE `owner`=%i AND `valid_until`>=%s', $userID, $now);
if(!$pickResult){
Json::die([
@@ -38,7 +47,6 @@ if(!$pickResult){
]);
}
$pickResult = Json::decode($pickResult);
if(!key_exists($pick, $pickResult)){
Json::die([
@@ -50,14 +58,9 @@ $pickedNPC = $pickResult[$pick];
$gencount = $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2');
list(
$year,
$month,
$maxgeneral,
$npcmode
) = $gameStor->getValuesAsArray(['year', 'month', 'maxgeneral', 'npcmode']);
if(!$npcmode){
$db->query("unlock tables");
Json::die([
'result'=>false,
'reason'=>'빙의 가능한 서버가 아닙니다'
@@ -65,12 +68,15 @@ if(!$npcmode){
}
if ($gencount >= $maxgeneral) {
$db->query("unlock tables");
Json::die([
'result'=>false,
'reason'=>'더 이상 등록 할 수 없습니다.'
]);
}
//등록 시작
$db->update('general', [
'name2'=>$userNick,
@@ -81,7 +87,10 @@ $db->update('general', [
'owner'=>$userID,
], 'owner <= 0 AND npc = 2 AND no = %i', $pick);
if(!$db->affectedRows()){
$db->query("unlock tables");
Json::die([
'result'=>false,
'reason'=>'장수 등록에 실패했습니다.'
@@ -90,6 +99,8 @@ if(!$db->affectedRows()){
$db->delete('select_npc_token', 'owner=%i or valid_until < %s', $userID, $now);
$db->query("unlock tables");
$josaYi = JosaUtil::pick($userNick, '이');
pushGeneralHistory($pickedNPC, "<C>●</>{$year}{$month}월:<Y>{$pickedNPC['name']}</>의 육체에 <Y>{$userNick}</>{$josaYi} 빙의되다.");
//pushGenLog($me, $mylog);
+47 -1
View File
@@ -3,6 +3,41 @@ namespace sammo;
include "lib.php";
$templates = new \League\Plates\Engine(__dir__.'/templates');
function getAutorunInfo($autorunOption){
global $templates;
$auto_info = [];
foreach($autorunOption['options'] as $auto_option => $value){
assert($value);
switch($auto_option){
case 'develop': $auto_info['내정'] = '내정'; break;
case 'warp': $auto_info['순간이동'] = '순간이동'; break;
case 'recruit': $auto_info['징병'] = $auto_info['징병']??'징병'; break;
case 'recruit_high': $auto_info['징병'] = '모병'; break;
case 'train': $auto_info['훈사'] = '훈련/사기진작'; break;
case 'battle': $auto_info['출병'] = '출병'; break;
}
}
$limit = Util::toInt($autorunOption['limit_minutes']);
if($limit >= 43200){
$auto_info['제한'] = '항상 유효';
}
else if($limit % 60 == 0){
$auto_info['제한'] = ($limit/60).'시간 유효';
}
else{
$auto_info['제한'] = ($limit).'분 유효';
}
$auto_info = join(', ', array_values($auto_info));
return $templates->render('tooltip', [
'text'=>'자율행동',
'info'=>$auto_info,
'style'=>'text-decoration:underline',
'copyable_info'=>true
]);
}
$session = Session::requireLogin([
'game'=>null,
'me'=>null
@@ -16,6 +51,7 @@ if(!class_exists('\\sammo\\DB')){
]);
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
@@ -38,6 +74,10 @@ if(file_exists(__dir__.'/.htaccess')){
$otherTextInfo[] = '랜덤 임관 전용';
}
if($options['autorun_user']['limit_minutes']??false){
$otherTextInfo[] = getAutorunInfo($options['autorun_user']);
}
if(!$otherTextInfo){
$otherTextInfo = '표준';
}
@@ -64,7 +104,7 @@ if(file_exists(__dir__.'/.htaccess')){
//TODO: 천통시에도 예약 오픈 알림이 필요..?
$admin = $gameStor->getValues(['isunited', 'npcmode', 'year', 'month', 'scenario', 'scenario_text', 'maxgeneral', 'turnterm', 'opentime', 'turntime', 'join_mode', 'fiction']);
$admin = $gameStor->getValues(['isunited', 'npcmode', 'year', 'month', 'scenario', 'scenario_text', 'maxgeneral', 'turnterm', 'opentime', 'turntime', 'join_mode', 'fiction', 'autorun_user']);
$admin['maxUserCnt'] = $admin['maxgeneral'];
$admin['npcMode'] = $admin['npcmode'];
$admin['turnTerm'] = $admin['turnterm'];
@@ -94,12 +134,18 @@ if($admin['join_mode'] == 'onlyRandom'){
$otherTextInfo[] = '랜덤 임관 전용';
}
if($admin['autorun_user']['limit_minutes']??false){
$otherTextInfo[] = getAutorunInfo($admin['autorun_user']);
}
if(!$otherTextInfo){
$otherTextInfo = '표준';
}
else{
$otherTextInfo = join(', ', $otherTextInfo);
}
$admin['otherTextInfo'] = $otherTextInfo;
$admin['defaultStatTotal'] = GameConst::$defaultStatTotal;
$me = [];
+10
View File
@@ -71,6 +71,8 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['year','month','maxgeneral','scenario','show_img_level','turnterm','turntime','genius','npcmode']);
########## 동일 정보 존재여부 확인. ##########
$db->query("lock tables general write, city read, storage read");
$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);
@@ -80,6 +82,7 @@ if ($oldGeneral) {
window.alert('이미 등록하셨습니다!')
history.go(-1)
</script>");
$db->query("unlock tables");
exit;
}
if ($oldName) {
@@ -87,6 +90,7 @@ if ($oldName) {
window.alert('이미 있는 장수입니다. 다른 이름으로 등록해 주세요!')
history.go(-1)
</script>");
$db->query("unlock tables");
exit;
}
if ($gameStor->maxgeneral <= $gencount) {
@@ -94,6 +98,7 @@ if ($gameStor->maxgeneral <= $gencount) {
window.alert('더이상 등록할 수 없습니다!')
history.go(-1)
</script>");
$db->query("unlock tables");
exit;
}
if (mb_strlen($name) < 1) {
@@ -101,6 +106,7 @@ if (mb_strlen($name) < 1) {
window.alert('이름이 짧습니다. 다시 가입해주세요!')
history.go(-1)
</script>");
$db->query("unlock tables");
exit;
}
if (mb_strlen($name) > 9) {
@@ -108,6 +114,7 @@ if (mb_strlen($name) > 9) {
window.alert('이름이 유효하지 않습니다. 다시 가입해주세요!')
history.go(-1)
</script>");
$db->query("unlock tables");
exit;
}
if ($leader + $power + $intel > GameConst::$defaultStatTotal) {
@@ -115,6 +122,7 @@ if ($leader + $power + $intel > GameConst::$defaultStatTotal) {
window.alert('능력치가 ".GameConst::$defaultStatTotal."을 넘어섰습니다. 다시 가입해주세요!')
history.go(-1)
</script>");
$db->query("unlock tables");
exit;
}
@@ -247,6 +255,8 @@ $db->insert('general', [
]);
$generalID = $db->insertId();
$db->query("unlock tables");
$cityname = CityConst::byID($city)->name;
$me = [
+31
View File
@@ -0,0 +1,31 @@
jQuery(function($){
var currYear = startYear;
var currMonth = startMonth;
var $yearMonth = $('#yearmonth');
var $elements = $();
var endDate = lastYear * 12 + lastMonth - 1;
var currDate = startYear * 12 + startMonth - 1;
while(currDate <= endDate){
var target = currYear*100 + currMonth;
var sel = '';
if(currYear == selectYear && currMonth == selectMonth){
sel = 'selected="selected"';
}
var option = $('<option value="{0}" {1} >{2}년 {3}월</option>'.format(target, sel, currYear, currMonth));
$elements = $elements.add(option);
currMonth += 1;
if(currMonth > 12){
currYear += 1;
currMonth -= 12;
}
currDate += 1;
}
$yearMonth.empty();
$yearMonth.append($elements);
});
+28
View File
@@ -105,6 +105,22 @@ function scenarioPreview(){
}
function formSetup(){
$.validator.addMethod("autorun_user", function(value,element){
var parent = $(element).parent('.input-group');
var checkCnt = parent.find('input:checked').length;
if(value <= 0){
if(checkCnt > 0){
return false;
}
return true;
}
if(checkCnt == 0){
return false;
}
return true;
}, "유효 시간과 옵션은 동시에 설정해야합니다.");
$('#game_form').validate({
rules:{
turnterm:"required",
@@ -116,6 +132,7 @@ function formSetup(){
show_img_level:"required",
tournament_trig:"required",
join_mode:'required',
autorun_user_minutes:{required: true, autorun_user: true, min:0}
},
errorElement: "div",
errorPlacement: function ( error, element ) {
@@ -140,6 +157,15 @@ function formSetup(){
if(!$("#game_form").valid()){
return;
}
var autorun_user_minutes = parseInt($('#autorun_user_minutes').val());
var autorun_user = [];
if(autorun_user_minutes > 0){
$('.autorun_user_chk:checked').each(function(){
autorun_user.push($(this).data('key'));
});
}
$.ajax({
cache:false,
type:'post',
@@ -157,6 +183,8 @@ function formSetup(){
reserve_open:$('#reserve_open').val(),
pre_reserve_open:$('#pre_reserve_open').val(),
join_mode:$('#join_mode input:radio:checked').val(),
autorun_user_minutes:autorun_user_minutes,
autorun_user:autorun_user
}
}).then(function(result){
var deferred = $.Deferred();
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+20
View File
@@ -0,0 +1,20 @@
function getCityPosition(){
return {"1":["태초마을",169,321],"2":["상록시티",169,231],"3":["회색시티",174,104],"4":["달맞이산",297,94],"5":["블루시티",452,92],"6":["갈색시티",451,278],"7":["보라타운",627,180],"8":["무지개시티",343,180],"9":["연분홍시티",357,377],"10":["노랑시티",451,180],"11":["홍련마을",169,454],"12":["챔피언로드(입구)",90,231],"13":["챔피언로드(동굴)",90,180],"14":["석영고원",90,29],"15":["사이클링로드(입구)",252,180],"16":["사이클링로드(출구)",252,377],"17":["관동15로",451,377],"18":["무인발전소",627,94],"19":["IC",627,278],"20":["관동13로",627,344],"21":["블루시티동굴",451,32],"22":["이수재의집",572,32],"23":["쌍둥이섬",263,454]};
}
function formatCityInfo(city) {
var regionMap = {"관동 지방":1,"1":"관동 지방"};
var levelMap = {"수":1,"1":"수","진":2,"2":"진","관":3,"3":"관","이":4,"4":"이","소":5,"5":"소","중":6,"6":"중","대":7,"7":"대","특":8,"8":"특"};
var region_str = regionMap[city.region];
var level_str = levelMap[city.level];
city.text = '【' + region_str + '|' + level_str + '】' + city.name;
city.region_str = region_str;
city.level_str = level_str;
return city;
}
+46 -6
View File
@@ -77,6 +77,9 @@ switch($commandtype) {
case 34: command_34($turn, 34); break; //파괴
case 35: command_35($turn, 35); break; //선동
case 38: command_Single($turn, 38); break; //내특 초기화
case 39: command_Single($turn, 39); break; //전특 초기화
case 41: command_Single($turn, 41); break; //단련
case 42: command_Single($turn, 42); break; //견문
case 43: command_43( $turn, 43); break; //증여
@@ -114,6 +117,7 @@ switch($commandtype) {
case 77: command_77($turn, 77); break; //이호경식
case 78: command_78($turn, 78); break; //급습
case 81: command_81($turn, 81); break; //국기변경
case 82: command_82($turn, 82); break; //국호변경
case 99: command_99($turn); break; //수뇌부 휴식
default:command_Single($turn, 0); break; //휴식
@@ -244,9 +248,8 @@ function command_11($turn, $command, bool $is모병 = false) {
foreach(GameUnitConst::byType($armType) as $unit){
$crewObj = new \stdClass;
if(!$unit->isValid($ownCities, $ownRegions, $relativeYear, $tech)){
continue; //TODO: 불가능한 병종도 보여줄 필요가 있음.
}
$crewObj->showDefault = 'true';
$crewObj->id = $unit->id;
@@ -256,6 +259,11 @@ function command_11($turn, $command, bool $is모병 = false) {
else{
$crewObj->bgcolor = 'limegreen';
}
if(!$unit->isValid($ownCities, $ownRegions, $relativeYear, $tech)){
$crewObj->showDefault = 'false';
$crewObj->bgcolor = 'red';
}
$crewObj->baseRice = $unit->rice * getTechCost($tech);
$crewObj->baseCost = CharCost($unit->costWithTech($tech), $me['personal']);
@@ -392,7 +400,8 @@ function command_16($turn, $command) {
echo getMapHtml();
echo "<br>
선택된 도시 침공을 합니다.<br>
선택된 도시 향해 침공을 합니다.<br>
침공 경로에 적군의 도시가 있다면 전투를 벌입니다.<br>
목록을 선택하거나 도시를 클릭하세요.<br>
<form name=form1 action=c_double.php method=post>
{$currentcity['name']} =>
@@ -414,8 +423,6 @@ function command_16($turn, $command) {
</form>
";
printCitiesBasedOnDistance($currentcity['city'], 1);
ender();
}
@@ -2614,3 +2621,36 @@ function command_81($turn, $command) {
";
ender(1);
}
function command_82($turn, $command) {
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$connect=$db->get();
$userID = Session::getUserID();
$nationID = $db->queryFirstField('SELECT nation FROM general WHERE owner = %i', $userID);
$nation = $db->queryFirstRow('SELECT level,aux FROM nation WHERE nation = %i', $nationID);
$nationAux = Json::decode($nation['aux']??'{}');
starter("국호변경");
if($nation && $nation['level'] == 7 && !($nationAux['used_82']??0)){
?>
나라의 이름을 바꿉니다. 황제가 1 가능합니다.<br>
<form name=form1 action=c_double.php method=post>
국명 : <input type=text name=name size=18 maxlength=9 style=text-align:right;color:white;background-color:black>
<input type=submit value='국호 변경'>
<input type=hidden name=command value=<?=$command?>>
<?php
for($i=0; $i < count($turn); $i++) {
echo "<input type=hidden name=turn[] value=$turn[$i]>";
}
echo "</form>";
} else {
echo "국호 변경이 불가능합니다.<br>";
}
ender();
}
+13
View File
@@ -74,6 +74,19 @@ class GameConstBase
/** @var int 최대 기술 레벨 */
public static $maxTechLevel = 12;
/** @var int 최소 인구 증가량 */
public static $basePopIncreaseAmount = 5000;
/** @var int 증축시 인구 증가량 */
public static $expandCityPopIncreaseAmount = 100000;
/** @var int 증축시 내정 증가량 */
public static $expandCityDevelIncreaseAmount = 2000;
/** @var int 증축시 성벽 증가량 */
public static $expandCityWallIncreaseAmount = 2000;
/** @var int 증축시 최소 비용 */
public static $expandCityDefaultCost = 60000;
/** @var int 증축시 비용 계수 */
public static $expandCityCostCoef = 500;
/** @var int 초기 제한시 장수 제한 */
public static $initialNationGenLimitForRandInit = 3;
+3 -1
View File
@@ -336,7 +336,9 @@ class GameUnitConstBase{
}
/**
* @return \sammo\GameUnitDetail[]
*/
public static function byType(int $type): array{
static::_generate();
if(!key_exists($type, static::$constType)){
+4 -2
View File
@@ -144,7 +144,8 @@ class ResetHelper{
int $show_img_level,
int $tournament_trig,
string $join_mode,
string $turntime
string $turntime,
?array $autorun_user
):array{
//FIXME: 분리할 것
if(120 % $turnterm != 0){
@@ -253,7 +254,8 @@ class ResetHelper{
'extended_general'=>$extend,
'fiction'=>$fiction,
'tnmt_trig'=>$tournament_trig,
'prev_winner'=>$prevWinner
'prev_winner'=>$prevWinner,
'autorun_user'=>$autorun_user
];
foreach(RootDB::db()->query('SELECT `no`, `name`, `picture`, `imgsvr` FROM member WHERE grade >= 5') as $admin){
+1 -1
View File
@@ -354,7 +354,7 @@ class Scenario{
'npc_cnt'=>count($this->getNPC()),
'npcEx_cnt'=>count($this->getNPCex()),
'npcNeutral_cnt'=>count($this->getNPCneutral()),
'nation'=>array_map(function($nation) use ($nationGeneralCnt, $nationGeneralExCnt){
'nation'=>array_map(function($nation) use ($nationGeneralCnt, $nationGeneralExCnt, $nationGeneralNeutralCnt){
$brief = $nation->getBrief();
$brief['generals'] = Util::array_get($nationGeneralCnt[$nation->getID()], 0);
$brief['generalsEx'] = Util::array_get($nationGeneralExCnt[$nation->getID()], 0);
+87
View File
@@ -0,0 +1,87 @@
<?php
namespace sammo;
class CityConst extends CityConstBase{
protected static $initCity = [
//id, 도시, 규모, 인구, 농, 상, 치, 성, 수,(x100)지역, x, y, 연결도시
[1, '낙양', '특', 6686, 78, 80, 67, 97, 99, '중원', 285, 176, ['하내', '홍농', '호로']],
[2, '성도', '특', 5220, 82, 83, 67, 100, 98, '서촉', 30, 285, ['덕양', '강주']],
[3, '건업', '특', 5109, 77, 82, 67, 92, 95, '오월', 507, 303, ['광릉', '합비', '오']],
[4, '업', '특', 4964, 83, 75, 67, 94, 98, '하북', 355, 135, ['하내', '거록', '남피', '제남', '진류']],
[5, '장안', '특', 4738, 77, 82, 67, 96, 94, '서북', 162, 173, ['안정', '오장원', '한중', '홍농']],
[6, '허창', '특', 4701, 81, 83, 67, 94, 100, '중원', 325, 218, ['호로', '진류', '초', '여남', '완']],
[7, '양양', '특', 4670, 80, 84, 67, 92, 94, '초', 259, 295, ['신야', '강릉', '강하']],
[8, '시상', '대', 4202, 65, 67, 53, 79, 77, '오월', 357, 357, ['적벽', '여강', '단양', '상동', '장사']],
[9, '수춘', '대', 4114, 66, 64, 53, 79, 76, '중원', 385, 270, ['여남', '초', '하비', '합비']],
[10, '한중', '대', 4110, 64, 67, 53, 82, 82, '서촉', 130, 218, ['무도', '오장원', '장안', '상용', '자동']],
[11, '남피', '대', 4026, 66, 67, 53, 81, 84, '하북', 410, 93, ['계', '북평', '평원', '업', '거록']],
[12, '위례', '대', 3941, 67, 62, 53, 78, 82, '동이', 618, 140, ['평양', '북해', '웅진', '계림']],
[13, '북평', '대', 3890, 68, 63, 53, 82, 79, '하북', 442, 53, ['계', '요동', '남피']],
[14, '강릉', '대', 3880, 70, 64, 53, 76, 77, '초', 245, 330, ['이릉', '양양', '적벽', '장사', '무릉']],
[15, '완', '대', 3779, 69, 67, 53, 81, 79, '중원', 275, 235, ['허창', '여남', '신야']],
[16, '장사', '대', 3768, 65, 66, 53, 80, 84, '초', 258, 373, ['강릉', '시상', '계양', '무릉']],
[17, '오', '중', 3484, 51, 54, 40, 62, 61, '오월', 515, 340, ['건업', '단양', '회계', '탐라']],
[18, '하비', '중', 3422, 57, 55, 40, 66, 62, '중원', 460, 240, ['패', '북해', '광릉', '수춘']],
[19, '복양', '중', 3348, 53, 55, 40, 66, 64, '중원', 412, 170, ['제남', '진류', '패']],
[20, '웅진', '중', 3326, 51, 53, 40, 62, 64, '동이', 615, 205, ['위례', '계림', '탐라']],
[21, '강주', '중', 3301, 53, 53, 40, 67, 65, '서촉', 75, 305, ['성도', '덕양', '영안', '주제', '월수']],
[22, '무도', '중', 3222, 51, 56, 40, 64, 68, '서촉', 55, 191, ['저', '한중', '자동']],
[23, '국내', '중', 3186, 52, 53, 40, 66, 62, '동이', 596, 48, ['요동', '오환', '평양']],
[24, '진류', '중', 3166, 55, 53, 40, 64, 66, '중원', 370, 175, ['업', '복양', '패', '초', '허창', '호로']],
[25, '계양', '중', 3164, 55, 53, 40, 65, 62, '초', 242, 408, ['영릉', '장사', '상동']],
[26, '계림', '중', 3129, 53, 49, 40, 65, 62, '동이', 660, 195, ['위례', '웅진', '왜']],
[27, '계', '중', 3108, 50, 53, 40, 62, 65, '하북', 386, 55, ['진양', '북평', '남피']],
[28, '무위', '중', 3099, 51, 53, 40, 66, 64, '서북', 56, 76, ['강', '안정', '천수', '저']],
[29, '제남', '중', 3065, 51, 54, 40, 67, 62, '하북', 402, 132, ['업', '평원', '복양']],
[30, '남해', '중', 3042, 55, 51, 40, 64, 65, '오월', 270, 474, ['상동', '산월', '교지']],
[31, '덕양', '중', 3042, 54, 56, 40, 63, 62, '서촉', 73, 276, ['자동', '영안', '강주', '성도']],
[32, '하내', '중', 2989, 51, 54, 40, 65, 64, '하북', 295, 140, ['진양', '업', '낙양', '하동']],
[33, '상용', '중', 2950, 52, 51, 40, 62, 65, '서촉', 190, 220, ['한중', '신야']],
[34, '초', '소', 2629, 40, 41, 27, 50, 46, '중원', 375, 225, ['허창', '진류', '패', '수춘', '여남']],
[35, '운남', '소', 2606, 41, 40, 27, 51, 49, '남중', 45, 405, ['월수', '건녕', '남만']],
[36, '대', '소', 2605, 40, 41, 27, 46, 48, '오월', 450, 470, ['산월', '회계', '왜']],
[37, '하동', '소', 2566, 40, 40, 27, 50, 44, '서북', 240, 140, ['흉노', '진양', '하내', '홍농']],
[38, '무릉', '소', 2557, 39, 42, 27, 50, 46, '초', 195, 352, ['강릉', '장사', '영릉']],
[39, '교지', '소', 2556, 39, 39, 27, 46, 47, '남중', 136, 480, ['남만', '남해']],
[40, '단양', '소', 2546, 41, 43, 27, 46, 46, '오월', 440, 350, ['여강', '오', '건안', '시상']],
[41, '영안', '소', 2522, 41, 39, 27, 46, 47, '서촉', 116, 282, ['덕양', '이릉', '강주']],
[42, '북해', '소', 2517, 37, 42, 27, 50, 46, '하북', 470, 150, ['평원', '위례', '하비']],
[43, '합비', '진', 798, 13, 13, 13, 31, 33, '중원', 420, 294, ['수춘', '건업', '여강']],
[44, '이릉', '진', 774, 12, 13, 13, 31, 33, '초', 188, 275, ['영안', '강릉']],
[45, '건녕', '소', 2466, 39, 39, 27, 50, 45, '남중', 85, 390, ['주제', '장가', '운남']],
[46, '강하', '소', 2459, 37, 37, 27, 46, 48, '초', 320, 299, ['양양', '적벽', '여강']],
[47, '진양', '소', 2459, 37, 39, 27, 51, 47, '하북', 310, 75, ['흉노', '하동', '하내', '거록', '계']],
[48, '평원', '소', 2459, 41, 43, 27, 49, 50, '하북', 445, 110, ['남피', '제남', '북해']],
[49, '회계', '소', 2404, 43, 39, 27, 50, 51, '오월', 485, 390, ['오', '건안', '대']],
[50, '천수', '소', 2388, 39, 43, 27, 48, 46, '서북', 76, 140, ['무위', '안정', '오장원', '저']],
[51, '평양', '소', 2351, 37, 39, 27, 48, 46, '동이', 606, 97, ['국내', '위례']],
[52, '요동', '소', 2350, 42, 39, 27, 47, 50, '동이', 549, 26, ['북평', '오환', '국내']],
[53, '거록', '소', 2349, 41, 38, 27, 51, 46, '하북', 355, 95, ['진양', '남피', '업']],
[54, '여강', '소', 2324, 37, 39, 27, 48, 44, '오월', 392, 325, ['합비', '단양', '시상', '강하']],
[55, '패', '소', 2302, 43, 39, 27, 46, 47, '중원', 425, 210, ['진류', '복양', '하비', '초']],
[56, '자동', '소', 2296, 38, 37, 27, 48, 46, '서촉', 62, 240, ['무도', '한중', '덕양']],
[57, '광릉', '소', 2294, 41, 37, 27, 48, 50, '오월', 478, 270, ['하비', '건업']],
[58, '장가', '소', 2282, 39, 41, 27, 46, 46, '남중', 136, 395, ['건녕', '영릉', '남만']],
[59, '영릉', '소', 2279, 41, 39, 27, 50, 50, '초', 197, 390, ['무릉', '계양', '장가']],
[60, '월수', '소', 2262, 40, 39, 27, 46, 50, '남중', 39, 349, ['강주', '주제', '운남']],
[61, '건안', '소', 2242, 38, 41, 27, 46, 50, '오월', 440, 420, ['단양', '회계', '산월']],
[62, '신야', '소', 2229, 40, 41, 27, 46, 44, '초', 245, 255, ['상용', '완', '양양']],
[63, '탐라', '수', 904, 15, 14, 13, 34, 33, '동이', 614, 259, ['웅진', '왜', '오']],
[64, '상동', '소', 2214, 39, 39, 27, 50, 46, '초', 285, 405, ['계양', '시상', '남해']],
[65, '안정', '소', 2211, 38, 39, 27, 46, 50, '서북', 135, 130, ['강', '무위', '천수', '장안']],
[66, '여남', '소', 2199, 42, 37, 27, 51, 51, '중원', 335, 255, ['완', '허창', '초', '수춘']],
[67, '홍농', '소', 2198, 38, 42, 27, 46, 50, '서북', 220, 170, ['하동', '낙양', '장안']],
[68, '주제', '소', 2197, 39, 41, 27, 49, 46, '남중', 93, 357, ['강주', '월수', '건녕']],
[69, '남만', '이', 1902, 27, 28, 13, 34, 36, '남중', 90, 454, ['운남', '장가', '교지']],
[70, '산월', '이', 1820, 27, 25, 13, 34, 30, '오월', 373, 447, ['건안', '대', '남해']],
[71, '오환', '이', 1722, 28, 25, 13, 34, 32, '동이', 628, 19, ['요동', '국내']],
[72, '강', '이', 1676, 27, 28, 13, 34, 32, '서북', 154, 70, ['무위', '안정']],
[73, '왜', '이', 1652, 26, 25, 13, 34, 33, '동이', 681, 292, ['계림', '탐라', '대']],
[74, '흉노', '이', 1651, 27, 27, 13, 32, 30, '서북', 227, 79, ['진양', '하동']],
[75, '저', '이', 1566, 27, 28, 13, 34, 34, '서북', 24, 123, ['무위', '천수', '무도']],
[76, '호로', '관', 766, 11, 13, 13, 76, 77, '중원', 317, 182, ['낙양', '진류', '허창']],
[77, '오장원', '진', 804, 13, 12, 13, 33, 32, '서북', 104, 175, ['천수', '장안', '한중']],
[78, '적벽', '수', 894, 15, 14, 13, 34, 33, '오월', 335, 330, ['강하', '강릉', '시상']]
];
}
+87
View File
@@ -0,0 +1,87 @@
<?php
namespace sammo;
class CityConst extends CityConstBase{
protected static $initCity = [
//id, 도시, 규모, 상, 치, 성, 수,(x100)지역, x, y, 연결도시
[1, '낙양', '소', 4163, 57, 60, 40, 61, 64, '중원', 285, 176, ['하내', '홍농', '호로']],
[2, '성도', '소', 3247, 63, 65, 40, 65, 63, '서촉', 30, 285, ['덕양', '강주']],
[3, '건업', '소', 3178, 56, 63, 40, 55, 59, '오월', 507, 303, ['광릉', '합비', '오']],
[4, '업', '소', 3087, 65, 53, 40, 57, 62, '하북', 355, 135, ['하내', '거록', '남피', '제남', '진류']],
[5, '장안', '소', 2946, 56, 63, 40, 60, 58, '서북', 162, 173, ['안정', '오장원', '한중', '홍농']],
[6, '허창', '소', 2923, 61, 64, 40, 57, 65, '중원', 325, 218, ['호로', '진류', '초', '여남', '완']],
[7, '양양', '소', 2903, 60, 66, 40, 55, 57, '초', 259, 295, ['신야', '강릉', '강하']],
[8, '시상', '소', 3116, 58, 60, 40, 59, 56, '오월', 357, 357, ['적벽', '여강', '단양', '상동', '장사']],
[9, '수춘', '소', 3061, 59, 56, 40, 59, 55, '중원', 385, 270, ['여남', '초', '하비', '합비']],
[10, '한중', '소', 3058, 56, 61, 40, 62, 63, '서촉', 130, 218, ['무도', '오장원', '장안', '상용', '자동']],
[11, '남피', '소', 3006, 59, 61, 40, 61, 65, '하북', 410, 93, ['계', '북평', '평원', '업', '거록']],
[12, '위례', '소', 2953, 60, 53, 40, 58, 63, '동이', 618, 140, ['평양', '북해', '웅진', '계림']],
[13, '북평', '소', 2921, 62, 55, 40, 63, 59, '하북', 442, 53, ['계', '요동', '남피']],
[14, '강릉', '소', 2915, 65, 56, 40, 55, 56, '초', 245, 330, ['이릉', '양양', '적벽', '장사', '무릉']],
[15, '완', '소', 2852, 63, 60, 40, 61, 59, '중원', 275, 235, ['허창', '여남', '신야']],
[16, '장사', '소', 2845, 57, 59, 40, 60, 65, '초', 258, 373, ['강릉', '시상', '계양', '무릉']],
[17, '오', '소', 3172, 57, 61, 40, 57, 56, '오월', 515, 340, ['건업', '단양', '회계', '탐라']],
[18, '하비', '소', 3134, 65, 63, 40, 62, 58, '중원', 460, 240, ['패', '북해', '광릉', '수춘']],
[19, '복양', '소', 3087, 60, 63, 40, 62, 60, '중원', 412, 170, ['제남', '진류', '패']],
[20, '웅진', '소', 3073, 57, 59, 40, 58, 60, '동이', 615, 205, ['위례', '계림', '탐라']],
[21, '강주', '소', 3058, 59, 60, 40, 64, 61, '서촉', 75, 305, ['성도', '덕양', '영안', '주제', '월수']],
[22, '무도', '소', 3008, 57, 64, 40, 60, 65, '서촉', 55, 191, ['저', '한중', '자동']],
[23, '국내', '소', 2986, 58, 60, 40, 63, 58, '동이', 596, 48, ['요동', '오환', '평양']],
[24, '진류', '소', 2973, 62, 60, 40, 60, 63, '중원', 370, 175, ['업', '복양', '패', '초', '허창', '호로']],
[25, '계양', '소', 2972, 63, 60, 40, 61, 57, '초', 242, 408, ['영릉', '장사', '상동']],
[26, '계림', '소', 2950, 60, 54, 40, 61, 58, '동이', 660, 195, ['위례', '웅진', '왜']],
[27, '계', '소', 2937, 55, 60, 40, 58, 61, '하북', 386, 55, ['진양', '북평', '남피']],
[28, '무위', '소', 2932, 57, 59, 40, 63, 60, '서북', 56, 76, ['강', '안정', '천수', '저']],
[29, '제남', '소', 2910, 57, 61, 40, 64, 57, '하북', 402, 132, ['업', '평원', '복양']],
[30, '남해', '소', 2896, 62, 56, 40, 60, 61, '오월', 270, 474, ['상동', '산월', '교지']],
[31, '덕양', '소', 2896, 61, 64, 40, 59, 57, '서촉', 73, 276, ['자동', '영안', '강주', '성도']],
[32, '하내', '소', 2863, 57, 61, 40, 61, 60, '하북', 295, 140, ['진양', '업', '낙양', '하동']],
[33, '상용', '소', 2838, 58, 56, 40, 57, 61, '서촉', 190, 220, ['한중', '신야']],
[34, '초', '소', 3286, 60, 62, 40, 62, 57, '중원', 375, 225, ['허창', '진류', '패', '수춘', '여남']],
[35, '운남', '소', 3258, 62, 60, 40, 64, 61, '남중', 45, 405, ['월수', '건녕', '남만']],
[36, '대', '소', 3256, 60, 62, 40, 57, 60, '오월', 450, 470, ['산월', '회계', '왜']],
[37, '하동', '소', 3208, 60, 60, 40, 62, 55, '서북', 240, 140, ['흉노', '진양', '하내', '홍농']],
[38, '무릉', '소', 3196, 58, 63, 40, 63, 58, '초', 195, 352, ['강릉', '장사', '영릉']],
[39, '교지', '소', 3195, 58, 59, 40, 58, 59, '남중', 136, 480, ['남만', '남해']],
[40, '단양', '소', 3183, 62, 64, 40, 58, 57, '오월', 440, 350, ['여강', '오', '건안', '시상']],
[41, '영안', '소', 3153, 62, 59, 40, 58, 59, '서촉', 116, 282, ['덕양', '이릉', '강주']],
[42, '북해', '소', 3146, 55, 63, 40, 63, 58, '하북', 470, 150, ['평원', '위례', '하비']],
[43, '합비', '진', 998, 20, 19, 20, 39, 41, '중원', 420, 294, ['수춘', '건업', '여강']],
[44, '이릉', '진', 968, 18, 19, 20, 39, 41, '초', 188, 275, ['영안', '강릉']],
[45, '건녕', '소', 3082, 58, 59, 40, 63, 56, '남중', 85, 390, ['주제', '장가', '운남']],
[46, '강하', '소', 3074, 55, 56, 40, 57, 60, '초', 320, 299, ['양양', '적벽', '여강']],
[47, '진양', '소', 3074, 56, 59, 40, 64, 59, '하북', 310, 75, ['흉노', '하동', '하내', '거록', '계']],
[48, '평원', '소', 3074, 62, 65, 40, 61, 63, '하북', 445, 110, ['남피', '제남', '북해']],
[49, '회계', '소', 3005, 64, 59, 40, 62, 64, '오월', 485, 390, ['오', '건안', '대']],
[50, '천수', '소', 2985, 59, 64, 40, 60, 58, '서북', 76, 140, ['무위', '안정', '오장원', '저']],
[51, '평양', '소', 2939, 55, 59, 40, 60, 58, '동이', 606, 97, ['국내', '위례']],
[52, '요동', '소', 2937, 63, 59, 40, 59, 63, '동이', 549, 26, ['북평', '오환', '국내']],
[53, '거록', '소', 2936, 61, 57, 40, 64, 58, '하북', 355, 95, ['진양', '남피', '업']],
[54, '여강', '소', 2905, 56, 58, 40, 60, 55, '오월', 392, 325, ['합비', '단양', '시상', '강하']],
[55, '패', '소', 2877, 64, 58, 40, 58, 59, '중원', 425, 210, ['진류', '복양', '하비', '초']],
[56, '자동', '소', 2870, 57, 55, 40, 60, 58, '서촉', 62, 240, ['무도', '한중', '덕양']],
[57, '광릉', '소', 2867, 61, 55, 40, 60, 62, '오월', 478, 270, ['하비', '건업']],
[58, '장가', '소', 2853, 59, 62, 40, 58, 57, '남중', 136, 395, ['건녕', '영릉', '남만']],
[59, '영릉', '소', 2849, 62, 58, 40, 62, 62, '초', 197, 390, ['무릉', '계양', '장가']],
[60, '월수', '소', 2828, 60, 59, 40, 58, 63, '남중', 39, 349, ['강주', '주제', '운남']],
[61, '건안', '소', 2802, 57, 62, 40, 58, 63, '오월', 440, 420, ['단양', '회계', '산월']],
[62, '신야', '소', 2786, 60, 62, 40, 58, 55, '초', 245, 255, ['상용', '완', '양양']],
[63, '탐라', '수', 1130, 22, 21, 20, 43, 41, '동이', 614, 259, ['웅진', '왜', '오']],
[64, '상동', '소', 2767, 58, 59, 40, 62, 58, '초', 285, 405, ['계양', '시상', '남해']],
[65, '안정', '소', 2764, 57, 59, 40, 57, 62, '서북', 135, 130, ['강', '무위', '천수', '장안']],
[66, '여남', '소', 2749, 63, 56, 40, 64, 64, '중원', 335, 255, ['완', '허창', '초', '수춘']],
[67, '홍농', '소', 2748, 57, 63, 40, 58, 63, '서북', 220, 170, ['하동', '낙양', '장안']],
[68, '주제', '소', 2746, 58, 61, 40, 61, 58, '남중', 93, 357, ['강주', '월수', '건녕']],
[69, '남만', '이', 2378, 40, 42, 20, 43, 45, '남중', 90, 454, ['운남', '장가', '교지']],
[70, '산월', '이', 2275, 40, 37, 20, 43, 38, '오월', 373, 447, ['건안', '대', '남해']],
[71, '오환', '이', 2153, 42, 37, 20, 43, 40, '동이', 628, 19, ['요동', '국내']],
[72, '강', '이', 2095, 40, 42, 20, 43, 40, '서북', 154, 70, ['무위', '안정']],
[73, '왜', '이', 2065, 39, 37, 20, 43, 41, '동이', 681, 292, ['계림', '탐라', '대']],
[74, '흉노', '이', 2064, 40, 41, 20, 40, 38, '서북', 227, 79, ['진양', '하동']],
[75, '저', '이', 1957, 40, 42, 20, 43, 42, '서북', 24, 123, ['무위', '천수', '무도']],
[76, '호로', '관', 958, 17, 19, 20, 95, 96, '중원', 317, 182, ['낙양', '진류', '허창']],
[77, '오장원', '진', 1005, 19, 18, 20, 41, 40, '서북', 104, 175, ['천수', '장안', '한중']],
[78, '적벽', '수', 1117, 23, 21, 20, 42, 41, '오월', 335, 330, ['강하', '강릉', '시상']],
];
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace sammo;
class CityConst extends CityConstBase{
public static $regionMap = [
'관동 지방'=>1,1=>'관동 지방',
];
protected static $initCity = [
//id, 도시, 규모, 인구, 농, 상, 치, 성, 수,(x100)지역, x, y, 연결도시
[ 1 , "태초마을", "",12000, 80, 80, 60, 80, 80, "관동 지방", 169 , 321 , ["상록시티", "홍련마을"]],
[ 2 , "상록시티", "", 9000, 60, 60, 40, 60, 60, "관동 지방", 169 , 231 , ["태초마을", "회색시티", "챔피언로드(입구)"]],
[ 3 , "회색시티", "",12000, 80, 80, 60, 80, 80, "관동 지방", 174 , 104 , ["상록시티", "달맞이산"]],
[ 4 , "달맞이산", "",12000, 80, 80, 60, 80, 80, "관동 지방", 297 , 94 , ["회색시티", "블루시티"]],
[ 5 , "블루시티", "",12000, 80, 80, 60, 80, 80, "관동 지방", 452 , 92 , ["달맞이산", "노랑시티", "무인발전소", "블루시티동굴"]],
[ 6 , "갈색시티", "",15000,100,100, 80,100,100, "관동 지방", 451 , 278 , ["IC", "노랑시티"]],
[ 7 , "보라타운", "",12000, 60, 60, 40, 60, 60, "관동 지방", 627 , 180 , ["IC", "노랑시티", "무인발전소"]],
[ 8 , "무지개시티", "",18000,120,120,100,120,120, "관동 지방", 343 , 180 , ["노랑시티", "사이클링로드(입구)"]],
[ 9 , "연분홍시티", "",18000,120,120,100,120,120, "관동 지방", 357 , 377 , ["사이클링로드(출구)", "관동15로", "쌍둥이섬"]],
[ 10 , "노랑시티", "",18000,120,120,100,120,120, "관동 지방", 451 , 180 , ["보라타운", "무지개시티", "블루시티", "갈색시티"]],
[ 11 , "홍련마을", "",12000, 80, 80, 60, 80, 80, "관동 지방", 169 , 454 , ["태초마을", "쌍둥이섬"]],
[ 12 , "챔피언로드(입구)", "",12000, 80, 80, 60, 80, 80, "관동 지방", 90 , 231 , ["상록시티", "챔피언로드(동굴)"]],
[ 13 , "챔피언로드(동굴)", "",15000,100,100, 80,100,100, "관동 지방", 90 , 180 , ["석영고원", "챔피언로드(입구)"]],
[ 14 , "석영고원", "",18000,120,120,100,120,120, "관동 지방", 90 , 29 , ["챔피언로드(동굴)"]],
[ 15 , "사이클링로드(입구)", "",12000, 80, 80, 60, 80, 80, "관동 지방", 252 , 180 , ["무지개시티", "사이클링로드(출구)"]],
[ 16 , "사이클링로드(출구)", "",15000,100,100, 80,100,100, "관동 지방", 252 , 377 , ["사이클링로드(입구)", "연분홍시티"]],
[ 17 , "관동15로", "",12000, 80, 80, 60, 80, 80, "관동 지방", 451 , 377 , ["연분홍시티", "관동13로"]],
[ 18 , "무인발전소", "",15000,100,100, 80,100,100, "관동 지방", 627 , 94 , ["보라타운", "블루시티"]],
[ 19 , "IC", "", 9000, 60, 60, 40, 60, 60, "관동 지방", 627 , 278 , ["갈색시티", "보라타운", "관동13로"]],
[ 20 , "관동13로", "", 9000, 60, 60, 40, 60, 60, "관동 지방", 627 , 344 , ["관동15로", "IC"]],
[ 21 , "블루시티동굴", "",12000, 80, 80, 60, 80, 80, "관동 지방", 451 , 32 , ["블루시티", "이수재의집"]],
[ 22 , "이수재의집", "",15000,100,100, 80,100,100, "관동 지방", 572 , 32 , ["블루시티동굴"]],
[ 23 , "쌍둥이섬", "", 9000, 60, 60, 40, 60, 60, "관동 지방", 263 , 454 , ["연분홍시티", "홍련마을"]],
];
}
+15
View File
@@ -0,0 +1,15 @@
{
"title":"【공백지】 소형β",
"startYear":180,
"map":{
"mapName":"miniche_b"
},
"history":[
],
"const": {
"expandCityPopIncreaseAmount": 80000,
"expandCityDevelIncreaseAmount": 1350,
"expandCityWallIncreaseAmount": 1600,
"defaultMaxGeneral":300
}
}
+226
View File
@@ -0,0 +1,226 @@
{
"title": "【가상모드21】 Poke-관동지방",
"startYear": 1993,
"history": [
"<C>●</>1996년 1월:<L><b>【PoKe-관동】</b></>",
"<C>●</>1996년 1월:<L><b>【포켓몬vs트레이너! 포켓몬이 될것인가 트레이너가 될것인가】</b></>"
],
"stat": {
"total": 240,
"min": 40,
"max": 110,
"npcMax": 90,
"chiefMin": 65
},
"iconPath": "포켓몬스터",
"fiction": 1,
"nation":[
],
"map": {
"mapName": "pokemon_v1",
"unitSet": "basic"
},
"const": {
"basePopIncreaseAmount": 15000,
"expandCityPopIncreaseAmount": 300000
},
"diplomacy":[],
"general":[
[0, "이상해씨", null, 0, null, 45, 49, 49, 0, 1973, 2100, null, null],
[0, "이상해풀", null, 0, null, 60, 62, 63, 0, 1973, 2100, null, null],
[0, "이상해꽃", null, 0, null, 80, 82, 83, 0, 1973, 2100, null, null],
[0, "파이리", null, 0, null, 39, 52, 43, 0, 1973, 2100, null, null],
[0, "리자드", null, 0, null, 58, 64, 58, 0, 1973, 2100, null, null],
[0, "리자몽", null, 0, null, 78, 84, 78, 0, 1973, 2100, null, null],
[0, "꼬부기", null, 0, null, 44, 48, 65, 0, 1973, 2100, null, null],
[0, "어니부기", null, 0, null, 59, 63, 80, 0, 1973, 2100, null, null],
[0, "거북왕", null, 0, null, 79, 83, 100, 0, 1973, 2100, null, null],
[0, "캐터피", null, 0, null, 45, 30, 35, 0, 1973, 2100, null, null],
[0, "단데기", null, 0, null, 50, 40, 55, 0, 1973, 2100, null, null],
[0, "버터플", null, 0, null, 60, 45, 60, 0, 1973, 2100, null, null],
[0, "뿔충이", null, 0, null, 40, 35, 30, 0, 1973, 2100, null, null],
[0, "딱충이", null, 0, null, 45, 25, 50, 0, 1973, 2100, null, null],
[0, "독침붕", null, 0, null, 65, 85, 40, 0, 1973, 2100, null, null],
[0, "구구", null, 0, null, 40, 45, 40, 0, 1973, 2100, null, null],
[0, "피죤", null, 0, null, 63, 60, 55, 0, 1973, 2100, null, null],
[0, "피죤투", null, 0, null, 83, 80, 75, 0, 1973, 2100, null, null],
[0, "꼬렛", null, 0, null, 30, 56, 35, 0, 1973, 2100, null, null],
[0, "레트라", null, 0, null, 55, 81, 60, 0, 1973, 2100, null, null],
[0, "깨비참", null, 0, null, 40, 60, 30, 0, 1973, 2100, null, null],
[0, "깨비드릴조", null, 0, null, 65, 90, 65, 0, 1973, 2100, null, null],
[0, "아보", null, 0, null, 35, 60, 44, 0, 1973, 2100, null, null],
[0, "아보크", null, 0, null, 60, 85, 69, 0, 1973, 2100, null, null],
[0, "피카츄", null, 0, null, 35, 55, 40, 0, 1973, 2100, null, null],
[0, "라이츄", null, 0, null, 60, 90, 55, 0, 1973, 2100, null, null],
[0, "모래두지", null, 0, null, 50, 75, 85, 0, 1973, 2100, null, null],
[0, "고지", null, 0, null, 75, 100, 110, 0, 1973, 2100, null, null],
[0, "니드런♀", null, 0, null, 55, 47, 52, 0, 1973, 2100, null, null],
[0, "니드리나", null, 0, null, 70, 62, 67, 0, 1973, 2100, null, null],
[0, "니드퀸", null, 0, null, 90, 92, 87, 0, 1973, 2100, null, null],
[0, "니드런♂", null, 0, null, 46, 57, 40, 0, 1973, 2100, null, null],
[0, "니드리노", null, 0, null, 61, 72, 57, 0, 1973, 2100, null, null],
[0, "니드킹", null, 0, null, 81, 102, 77, 0, 1973, 2100, null, null],
[0, "삐삐", null, 0, null, 70, 45, 48, 0, 1973, 2100, null, null],
[0, "픽시", null, 0, null, 95, 70, 73, 0, 1973, 2100, null, null],
[0, "식스테일", null, 0, null, 38, 41, 40, 0, 1973, 2100, null, null],
[0, "나인테일", null, 0, null, 73, 76, 75, 0, 1973, 2100, null, null],
[0, "푸린", null, 0, null, 115, 45, 20, 0, 1973, 2100, null, null],
[0, "푸크린", null, 0, null, 140, 70, 45, 0, 1973, 2100, null, null],
[0, "주뱃", null, 0, null, 40, 45, 35, 0, 1973, 2100, null, null],
[0, "골뱃", null, 0, null, 75, 80, 70, 0, 1973, 2100, null, null],
[0, "뚜벅쵸", null, 0, null, 45, 50, 55, 0, 1973, 2100, null, null],
[0, "냄새꼬", null, 0, null, 60, 65, 70, 0, 1973, 2100, null, null],
[0, "라플레시아", null, 0, null, 75, 80, 85, 0, 1973, 2100, null, null],
[0, "파라스", null, 0, null, 35, 70, 55, 0, 1973, 2100, null, null],
[0, "파라섹트", null, 0, null, 60, 95, 80, 0, 1973, 2100, null, null],
[0, "콘팡", null, 0, null, 60, 55, 50, 0, 1973, 2100, null, null],
[0, "도나리", null, 0, null, 70, 65, 60, 0, 1973, 2100, null, null],
[0, "디그다", null, 0, null, 10, 55, 25, 0, 1973, 2100, null, null],
[0, "닥트리오", null, 0, null, 35, 80, 50, 0, 1973, 2100, null, null],
[0, "나옹", null, 0, null, 40, 45, 35, 0, 1973, 2100, null, null],
[0, "페르시온", null, 0, null, 65, 70, 60, 0, 1973, 2100, null, null],
[0, "고라파덕", null, 0, null, 50, 52, 48, 0, 1973, 2100, null, null],
[0, "골덕", null, 0, null, 80, 82, 78, 0, 1973, 2100, null, null],
[0, "망키", null, 0, null, 40, 80, 35, 0, 1973, 2100, null, null],
[0, "성원숭", null, 0, null, 65, 105, 60, 0, 1973, 2100, null, null],
[0, "가디", null, 0, null, 55, 70, 45, 0, 1973, 2100, null, null],
[0, "윈디", null, 0, null, 80, 100, 70, 0, 1973, 2100, null, null],
[0, "발챙이", null, 0, null, 40, 50, 40, 0, 1973, 2100, null, null],
[0, "슈륙챙이", null, 0, null, 65, 65, 65, 0, 1973, 2100, null, null],
[0, "강챙이", null, 0, null, 80, 85, 85, 0, 1973, 2100, null, null],
[0, "캐이시", null, 0, null, 25, 20, 15, 0, 1973, 2100, null, null],
[0, "윤겔라", null, 0, null, 40, 35, 30, 0, 1973, 2100, null, null],
[0, "메가후딘", null, 0, null, 55, 50, 65, 0, 1973, 2100, null, null],
[0, "후딘", null, 0, null, 55, 50, 45, 0, 1973, 2100, null, null],
[0, "알통몬", null, 0, null, 70, 80, 50, 0, 1973, 2100, null, null],
[0, "근육몬", null, 0, null, 70, 90, 60, 0, 1973, 2100, null, null],
[0, "괴력몬", null, 0, null, 90, 105, 75, 0, 1973, 2100, null, null],
[0, "모다피", null, 0, null, 50, 75, 35, 0, 1973, 2100, null, null],
[0, "우츠동", null, 0, null, 65, 90, 50, 0, 1973, 2100, null, null],
[0, "우츠보트", null, 0, null, 80, 105, 65, 0, 1973, 2100, null, null],
[0, "왕눈해", null, 0, null, 40, 40, 35, 0, 1973, 2100, null, null],
[0, "독파리", null, 0, null, 80, 70, 65, 0, 1973, 2100, null, null],
[0, "꼬마돌", null, 0, null, 40, 80, 100, 0, 1973, 2100, null, null],
[0, "데구리", null, 0, null, 55, 95, 115, 0, 1973, 2100, null, null],
[0, "딱구리", null, 0, null, 70, 110, 110, 0, 1973, 2100, null, null],
[0, "포니타", null, 0, null, 50, 85, 55, 0, 1973, 2100, null, null],
[0, "날쌩마", null, 0, null, 65, 90, 60, 0, 1973, 2100, null, null],
[0, "야돈", null, 0, null, 90, 65, 65, 0, 1973, 2100, null, null],
[0, "야도란", null, 0, null, 85, 65, 100, 0, 1973, 2100, null, null],
[0, "코일", null, 0, null, 25, 35, 70, 0, 1973, 2100, null, null],
[0, "레어코일", null, 0, null, 50, 60, 95, 0, 1973, 2100, null, null],
[0, "파오리", null, 0, null, 52, 65, 55, 0, 1973, 2100, null, null],
[0, "두두", null, 0, null, 35, 85, 45, 0, 1973, 2100, null, null],
[0, "두트리오", null, 0, null, 60, 95, 45, 0, 1973, 2100, null, null],
[0, "쥬쥬", null, 0, null, 65, 45, 55, 0, 1973, 2100, null, null],
[0, "쥬레곤", null, 0, null, 90, 70, 80, 0, 1973, 2100, null, null],
[0, "질퍽이", null, 0, null, 80, 80, 50, 0, 1973, 2100, null, null],
[0, "질뻐기", null, 0, null, 90, 90, 75, 0, 1973, 2100, null, null],
[0, "셀러", null, 0, null, 30, 65, 95, 0, 1973, 2100, null, null],
[0, "파르셀", null, 0, null, 50, 95, 100, 0, 1973, 2100, null, null],
[0, "고오스", null, 0, null, 30, 35, 30, 0, 1973, 2100, null, null],
[0, "고우스트", null, 0, null, 45, 50, 45, 0, 1973, 2100, null, null],
[0, "메가팬텀", null, 0, null, 60, 65, 80, 0, 1973, 2100, null, null],
[0, "팬텀", null, 0, null, 60, 65, 60, 0, 1973, 2100, null, null],
[0, "롱스톤", null, 0, null, 35, 45, 100, 0, 1973, 2100, null, null],
[0, "슬리프", null, 0, null, 60, 48, 45, 0, 1973, 2100, null, null],
[0, "슬리퍼", null, 0, null, 85, 73, 70, 0, 1973, 2100, null, null],
[0, "크랩", null, 0, null, 40, 95, 80, 0, 1973, 2100, null, null],
[0, "킹크랩", null, 0, null, 55, 105, 95, 0, 1973, 2100, null, null],
[0, "찌리리공", null, 0, null, 40, 30, 50, 0, 1973, 2100, null, null],
[0, "붐볼", null, 0, null, 60, 50, 70, 0, 1973, 2100, null, null],
[0, "아라리", null, 0, null, 60, 40, 80, 0, 1973, 2100, null, null],
[0, "나시", null, 0, null, 95, 95, 85, 0, 1973, 2100, null, null],
[0, "탕구리", null, 0, null, 50, 50, 95, 0, 1973, 2100, null, null],
[0, "텅구리", null, 0, null, 60, 80, 98, 0, 1973, 2100, null, null],
[0, "시라소몬", null, 0, null, 50, 95, 53, 0, 1973, 2100, null, null],
[0, "홍수몬", null, 0, null, 50, 95, 79, 0, 1973, 2100, null, null],
[0, "내루미", null, 0, null, 90, 55, 75, 0, 1973, 2100, null, null],
[0, "또가스", null, 0, null, 40, 65, 95, 0, 1973, 2100, null, null],
[0, "또도가스", null, 0, null, 65, 90, 120, 0, 1973, 2100, null, null],
[0, "뿔카노", null, 0, null, 80, 85, 95, 0, 1973, 2100, null, null],
[0, "코뿌리", null, 0, null, 85, 99, 80, 0, 1973, 2100, null, null],
[0, "럭키", null, 0, null, 100, 75, 75, 0, 1973, 2100, null, null],
[0, "덩쿠리", null, 0, null, 65, 55, 115, 0, 1973, 2100, null, null],
[0, "캥카", null, 0, null, 95, 85, 60, 0, 1973, 2100, null, null],
[0, "쏘드라", null, 0, null, 30, 40, 70, 0, 1973, 2100, null, null],
[0, "시드라", null, 0, null, 65, 65, 95, 0, 1973, 2100, null, null],
[0, "콘치", null, 0, null, 45, 67, 60, 0, 1973, 2100, null, null],
[0, "왕콘치", null, 0, null, 80, 92, 65, 0, 1973, 2100, null, null],
[0, "별가사리", null, 0, null, 30, 45, 55, 0, 1973, 2100, null, null],
[0, "아쿠스타", null, 0, null, 60, 75, 85, 0, 1973, 2100, null, null],
[0, "마임맨", null, 0, null, 40, 45, 65, 0, 1973, 2100, null, null],
[0, "스라크", null, 0, null, 70, 99, 80, 0, 1973, 2100, null, null],
[0, "루주라", null, 0, null, 65, 50, 35, 0, 1973, 2100, null, null],
[0, "에레브", null, 0, null, 65, 83, 57, 0, 1973, 2100, null, null],
[0, "마그마", null, 0, null, 65, 95, 57, 0, 1973, 2100, null, null],
[0, "쁘사이저", null, 0, null, 65, 93, 80, 0, 1973, 2100, null, null],
[0, "켄타로스", null, 0, null, 75, 90, 85, 0, 1973, 2100, null, null],
[0, "잉어킹", null, 0, null, 20, 10, 55, 0, 1973, 2100, null, null],
[0, "갸라도스", null, 0, null, 85, 99, 69, 0, 1973, 2100, null, null],
[0, "라프라스", null, 0, null, 100, 75, 65, 0, 1973, 2100, null, null],
[0, "메타몽", null, 0, null, 50, 50, 50, 0, 1973, 2100, null, null],
[0, "이브이", null, 0, null, 55, 55, 50, 0, 1973, 2100, null, null],
[0, "샤미드", null, 0, null, 95, 65, 60, 0, 1973, 2100, null, null],
[0, "쥬피썬더", null, 0, null, 65, 65, 95, 0, 1973, 2100, null, null],
[0, "부스터", null, 0, null, 65, 95, 60, 0, 1973, 2100, null, null],
[0, "폴리곤", null, 0, null, 65, 60, 70, 0, 1973, 2100, null, null],
[0, "암나이트", null, 0, null, 35, 40, 80, 0, 1973, 2100, null, null],
[0, "암스타", null, 0, null, 70, 60, 95, 0, 1973, 2100, null, null],
[0, "투구", null, 0, null, 50, 60, 70, 0, 1973, 2100, null, null],
[0, "투구푸스", null, 0, null, 60, 85, 90, 0, 1973, 2100, null, null],
[0, "프테라", null, 0, null, 80, 105, 65, 0, 1973, 2100, null, null],
[0, "잠만보", null, 0, null, 88, 91, 70, 0, 1973, 2100, null, null],
[0, "프리져", null, 0, null, 80, 85, 90, 0, 1973, 2100, "은둔", null],
[0, "썬더", null, 0, null, 85, 85, 80, 0, 1973, 2100, "은둔", null],
[0, "파이어", null, 0, null, 85, 95, 80, 0, 1973, 2100, "은둔", null],
[0, "미뇽", null, 0, null, 41, 64, 45, 0, 1973, 2100, null, null],
[0, "신뇽", null, 0, null, 61, 84, 65, 0, 1973, 2100, null, null],
[0, "망나뇽", null, 0, null, 91, 100, 95, 0, 1973, 2100, null, null],
[0, "뮤츠", null, 0, null, 101, 105, 90, 0, 1973, 2100, "은둔", null],
[0, "뮤", null, 0, null, 95, 95, 95, 0, 1973, 2100, "은둔", null]
],
"general_ex":[
[0, "갬블러", null, 0, null, 65, 65, 65, 0, 1973, 2100, null, null],
[0, "곤충채집소년", null, 0, null, 65, 66, 68, 0, 1973, 2100, null, null],
[0, "포켓몬 매니아", null, 0, null, 67, 52, 69, 0, 1973, 2100, null, null],
[0, "연구원", null, 0, null, 66, 63, 71, 0, 1973, 2100, null, null],
[0, "주술사", null, 0, null, 69, 53, 59, 0, 1973, 2100, null, null],
[0, "낚시꾼", null, 0, null, 75, 60, 56, 0, 1973, 2100, null, null],
[0, "등산가", null, 0, null, 58, 81, 63, 0, 1973, 2100, null, null],
[0, "맹수 조련사", null, 0, null, 77, 77, 53, 0, 1973, 2100, null, null],
[0, "반바지 꼬마", null, 0, null, 77, 51, 58, 0, 1973, 2100, null, null],
[0, "짧은 치마", null, 0, null, 68, 52, 80, 0, 1973, 2100, null, null],
[0, "불난집 전문 털이범", null, 0, null, 64, 79, 77, 0, 1973, 2100, null, null],
[0, "새 조련사", null, 0, null, 75, 73, 55, 0, 1973, 2100, null, null],
[0, "선원", null, 0, null, 71, 72, 61, 0, 1973, 2100, null, null],
[0, "수영팬티 소년", null, 0, null, 76, 75, 68, 0, 1973, 2100, null, null],
[0, "신사", null, 0, null, 75, 66, 51, 0, 1973, 2100, null, null],
[0, "엘리트 트레이너", null, 0, null, 83, 77, 55, 0, 1973, 2100, null, null],
[0, "아가씨", null, 0, null, 69, 58, 65, 0, 1973, 2100, null, null],
[0, "이과계남자", null, 0, null, 59, 61, 55, 0, 1973, 2100, null, "저격"],
[0, "전기 작업원", null, 0, null, 80, 70, 58, 0, 1973, 2100, null, null],
[0, "전기 그룹", null, 0, null, 70, 75, 55, 0, 1973, 2100, null, null],
[0, "저글러", null, 0, null, 69, 52, 63, 0, 1973, 2100, null, null],
[0, "초능력자", null, 0, null, 71, 47, 82, 0, 1973, 2100, null, null],
[0, "캠프보이", null, 0, null, 75, 60, 55, 0, 1973, 2100, null, null],
[0, "피크닉걸", null, 0, null, 55, 71, 63, 0, 1973, 2100, null, null],
[0, "태권왕", null, 0, null, 65, 50, 78, 0, 1973, 2100, null, "견고"],
[0, "폭주족", null, 0, null, 65, 58, 73, 0, 1973, 2100, null, null],
[0, "대머리", null, 0, null, 54, 60, 78, 0, 1973, 2100, null, null],
[0, "웅", null, 0, "회색시티", 81, 77, 71, 0, 1973, 2100, null, null],
[0, "이슬", null, 0, "블루시티", 81, 73, 72, 0, 1973, 2100, null, null],
[0, "마티스", null, 0, "갈색시티", 90, 77, 77, 0, 1973, 2100, null, null],
[0, "민화", null, 0, "무지개시티", 77, 85, 85, 0, 1973, 2100, null, null],
[0, "독수", null, 0, "연분홍시티", 81, 83, 80, 0, 1973, 2100, null, null],
[0, "초련", null, 0, "노랑시티", 78, 79, 84, 0, 1973, 2100, null, null],
[0, "강연", null, 0, "홍련마을", 95, 74, 78, 0, 1973, 2100, null, null],
[0, "비주기", null, 0, null, 90, 85, 90, 0, 1973, 2100, null, null],
[0, "칸나", null, 0, "석영고원", 91, 85, 89, 0, 1973, 2100, null, null],
[0, "시바", null, 0, "석영고원", 90, 100, 70, 0, 1973, 2100, null, null],
[0, "국화", null, 0, "석영고원", 83, 87, 88, 0, 1973, 2100, null, "환술"],
[0, "목호", null, 0, "석영고원", 94, 73, 94, 0, 1973, 2100, null, null],
[0, "로켓단", null, 0, null, 85, 85, 85, 0, 1973, 2100, null, null, "우리가 그렇게 궁금하시다면 대답해 드리는게 인지상정\n이 세계의 파괴를 막기 위해! 이 세계의 평화를 지키기 위해! \n사랑과 진실, 어둠을 뿌리고 다니는...! \n포켓몬의 감초 귀"]
]
}
+663
View File
@@ -0,0 +1,663 @@
{
"title": "【가상모드22】 찐유저무쌍!",
"startYear": 180,
"history": [
"<C>●</>180년 1월:<L><b>【가상모드22】</b>찐유저무쌍!</>",
"<C>●</>180년 1월:<L><b>【이벤트】</b></>다 덤벼라! 유저가 최강이다!"
],
"stat": {
"total": 310,
"min": 40,
"max": 140
},
"iconPath": ".",
"fiction": 1,
"nation":[
],
"diplomacy":[],
"general":[
[0, "아회남", null, 0, null, 65, 74, 26, 0, 160, 300, null, null],
[0, "이적", null, 0, null, 40, 24, 84, 0, 160, 300, null, null],
[0, "윤상", null, 0, null, 51, 44, 62, 0, 160, 300, null, null],
[0, "윤묵", null, 0, null, 26, 15, 66, 0, 160, 300, null, null],
[0, "우금", null, 0, null, 85, 82, 62, 0, 160, 300, null, null],
[0, "위관", null, 0, null, 69, 46, 79, 0, 160, 300, null, null],
[0, "원윤", null, 0, null, 32, 14, 39, 0, 160, 300, null, null],
[0, "원희", null, 0, null, 66, 43, 63, 0, 160, 300, null, null],
[0, "염행", null, 0, null, 78, 90, 58, 0, 160, 300, null, null],
[0, "염유", null, 0, null, 71, 50, 71, 0, 160, 300, null, null],
[0, "원술", null, 0, null, 76, 55, 75, 0, 160, 300, null, null, "천한 것들관 상종을 하면 안돼"],
[0, "원상", null, 0, null, 63, 75, 42, 0, 160, 300, null, null],
[0, "원소", null, 0, null, 90, 62, 81, 0, 160, 300, null, null],
[0, "염상", null, 0, null, 40, 27, 71, 0, 160, 300, null, null],
[0, "원담", null, 0, null, 60, 78, 30, 0, 160, 300, null, null],
[0, "염포", null, 0, null, 40, 25, 82, 0, 160, 300, null, null],
[0, "왕위", null, 0, null, 60, 70, 48, 0, 160, 300, null, null],
[0, "왕윤", null, 0, null, 26, 6, 68, 0, 160, 300, null, null],
[0, "왕항", null, 0, null, 76, 43, 61, 0, 160, 300, null, null],
[0, "왕찬", null, 0, null, 15, 3, 79, 0, 160, 300, null, null],
[0, "왕수", null, 0, null, 54, 27, 77, 0, 160, 300, null, null],
[0, "왕숙", null, 0, null, 36, 22, 76, 0, 160, 300, null, null],
[0, "왕준", null, 0, null, 85, 64, 84, 0, 160, 300, null, null],
[0, "왕쌍", null, 0, null, 67, 88, 19, 0, 160, 300, null, null],
[0, "왕창", null, 0, null, 74, 57, 79, 0, 160, 300, null, null],
[0, "왕평", null, 0, null, 88, 81, 61, 0, 160, 300, null, null],
[0, "왕보", null, 0, null, 62, 41, 79, 0, 160, 300, null, null],
[0, "왕문", null, 0, null, 65, 64, 31, 0, 160, 300, null, null],
[0, "왕릉", null, 0, null, 74, 50, 71, 0, 160, 300, null, null],
[0, "왕루", null, 0, null, 28, 30, 79, 0, 160, 300, null, null],
[0, "왕랑", null, 0, null, 47, 35, 79, 0, 160, 300, null, null],
[0, "온회", null, 0, null, 62, 36, 74, 0, 160, 300, null, null],
[0, "하안", null, 0, null, 15, 30, 72, 0, 160, 300, null, null],
[0, "괴월", null, 0, null, 50, 38, 85, 0, 160, 300, null, null],
[0, "괴량", null, 0, null, 68, 33, 88, 0, 160, 300, null, null],
[0, "가화", null, 0, null, 49, 65, 41, 0, 160, 300, null, null],
[0, "가규", null, 0, null, 78, 61, 84, 0, 160, 300, null, null],
[0, "하의", null, 0, null, 56, 69, 36, 0, 160, 300, null, null],
[0, "화흠", null, 0, null, 51, 33, 88, 0, 160, 300, null, null],
[0, "가후", null, 0, null, 71, 40, 98, 0, 160, 300, null, null, "이기기 위한 전략만 내드리겠습니다"],
[0, "곽가", null, 0, null, 70, 41, 97, 0, 160, 300, null, null, "조공을 위한 명이 조금만 더 남았다면..."],
[0, "악환", null, 0, null, 65, 80, 42, 0, 160, 300, null, null],
[0, "곽사", null, 0, null, 64, 76, 13, 0, 160, 300, null, null],
[0, "악취", null, 0, null, 53, 66, 61, 0, 160, 300, null, null],
[0, "곽준", null, 0, null, 73, 52, 73, 0, 160, 300, null, null],
[0, "학소", null, 0, null, 88, 63, 83, 0, 160, 300, null, null],
[0, "악진", null, 0, null, 80, 85, 56, 0, 160, 300, null, null],
[0, "곽도", null, 0, null, 62, 50, 82, 0, 160, 300, null, null],
[0, "학맹", null, 0, null, 62, 67, 42, 0, 160, 300, null, null],
[0, "곽유지", null, 0, null, 28, 9, 69, 0, 160, 300, null, null],
[0, "곽익", null, 0, null, 73, 69, 69, 0, 160, 300, null, null],
[0, "곽회", null, 0, null, 90, 66, 85, 0, 160, 300, null, null],
[0, "하후위", null, 0, null, 71, 73, 49, 0, 160, 300, null, null],
[0, "하후연", null, 0, null, 95, 92, 72, 0, 160, 300, null, null, "궁술로 날 당해낼 자가 있을까?"],
[0, "하후은", null, 0, null, 63, 72, 53, 0, 160, 300, null, null],
[0, "하후화", null, 0, null, 48, 51, 71, 0, 160, 300, null, null],
[0, "하후혜", null, 0, null, 50, 44, 76, 0, 160, 300, null, null],
[0, "하후현", null, 0, null, 54, 39, 76, 0, 160, 300, null, null],
[0, "하후상", null, 0, null, 79, 55, 75, 0, 160, 300, null, null],
[0, "하후덕", null, 0, null, 69, 73, 32, 0, 160, 300, null, null],
[0, "하후돈", null, 0, null, 91, 88, 68, 0, 160, 300, null, null],
[0, "하후패", null, 0, null, 79, 85, 63, 0, 160, 300, null, null],
[0, "하후무", null, 0, null, 20, 7, 4, 0, 160, 300, null, null],
[0, "가충", null, 0, null, 54, 31, 89, 0, 160, 300, null, null],
[0, "하진", null, 0, null, 68, 54, 75, 0, 160, 300, null, null],
[0, "화웅", null, 0, null, 78, 90, 55, 0, 160, 300, null, null],
[0, "한윤", null, 0, null, 26, 29, 65, 0, 160, 300, null, null],
[0, "관우", null, 0, null, 96, 99, 76, 0, 160, 300, null, null, "차가 식기 전에 적장의 목을 베어 오겠소!"],
[0, "환계", null, 0, null, 25, 26, 68, 0, 160, 300, null, null],
[0, "관해", null, 0, null, 70, 82, 10, 0, 160, 300, null, null],
[0, "관구검", null, 0, null, 84, 86, 62, 0, 160, 300, null, null],
[0, "한현", null, 0, null, 22, 33, 7, 0, 160, 300, null, null],
[0, "한호", null, 0, null, 73, 61, 84, 0, 160, 300, null, null],
[0, "관흥", null, 0, null, 76, 84, 62, 0, 160, 300, null, null],
[0, "관색", null, 0, null, 74, 83, 56, 0, 160, 300, null, null],
[0, "한수", null, 0, null, 78, 58, 79, 0, 160, 300, null, null],
[0, "한숭", null, 0, null, 25, 15, 71, 0, 160, 300, null, null],
[0, "관정", null, 0, null, 36, 52, 73, 0, 160, 300, null, null],
[0, "한섬", null, 0, null, 69, 66, 36, 0, 160, 300, null, null],
[0, "감택", null, 0, null, 51, 49, 83, 0, 160, 300, null, null],
[0, "한충", null, 0, null, 64, 67, 18, 0, 160, 300, null, null],
[0, "한당", null, 0, null, 76, 85, 61, 0, 160, 300, null, null],
[0, "한덕", null, 0, null, 63, 76, 25, 0, 160, 300, null, null],
[0, "감녕", null, 0, null, 92, 95, 74, 0, 160, 300, null, null],
[0, "한복", null, 0, null, 28, 3, 27, 0, 160, 300, null, null],
[0, "관평", null, 0, null, 78, 82, 60, 0, 160, 300, null, null],
[0, "간옹", null, 0, null, 20, 32, 75, 0, 160, 300, null, null],
[0, "안량", null, 0, null, 88, 96, 43, 0, 160, 300, null, null],
[0, "위연", null, 0, null, 91, 90, 70, 0, 160, 300, null, null],
[0, "국의", null, 0, null, 84, 78, 51, 0, 160, 300, null, null],
[0, "희지재", null, 0, null, 63, 35, 91, 0, 160, 300, null, null],
[0, "위속", null, 0, null, 67, 78, 31, 0, 160, 300, null, null],
[0, "위유", null, 0, null, 46, 29, 74, 0, 160, 300, null, null],
[0, "우금2", null, 0, null, 72, 79, 38, 0, 160, 300, null, null],
[0, "우보", null, 0, null, 38, 60, 21, 0, 160, 300, null, null],
[0, "강유", null, 0, null, 92, 72, 93, 0, 160, 300, null, null],
[0, "공지", null, 0, null, 43, 53, 62, 0, 160, 300, null, null],
[0, "교유", null, 0, null, 64, 69, 38, 0, 160, 300, null, null],
[0, "공도", null, 0, null, 59, 70, 23, 0, 160, 300, null, null],
[0, "허공", null, 0, null, 44, 66, 64, 0, 160, 300, null, null],
[0, "허정", null, 0, null, 23, 5, 68, 0, 160, 300, null, null],
[0, "허저", null, 0, null, 74, 97, 36, 0, 160, 300, null, null],
[0, "허유", null, 0, null, 36, 21, 80, 0, 160, 300, null, null],
[0, "기령", null, 0, null, 85, 84, 51, 0, 160, 300, null, null],
[0, "김의", null, 0, null, 32, 38, 65, 0, 160, 300, null, null],
[0, "김배삼결", null, 0, null, 64, 76, 19, 0, 160, 300, null, null],
[0, "김선", null, 0, null, 52, 68, 13, 0, 160, 300, null, null],
[0, "우번", null, 0, null, 46, 46, 87, 0, 160, 300, null, null],
[0, "형도영", null, 0, null, 69, 79, 41, 0, 160, 300, null, null],
[0, "엄안", null, 0, null, 82, 83, 62, 0, 160, 300, null, null],
[0, "엄망", null, 0, null, 68, 71, 40, 0, 160, 300, null, null],
[0, "엄준", null, 0, null, 41, 12, 71, 0, 160, 300, null, null],
[0, "엄정", null, 0, null, 50, 55, 39, 0, 160, 300, null, null],
[0, "엄백호", null, 0, null, 67, 70, 42, 0, 160, 300, null, null],
[0, "엄여", null, 0, null, 61, 78, 44, 0, 160, 300, null, null],
[0, "오의", null, 0, null, 79, 73, 53, 0, 160, 300, null, null],
[0, "황개", null, 0, null, 80, 86, 64, 0, 160, 300, null, null],
[0, "고간", null, 0, null, 74, 56, 38, 0, 160, 300, null, null],
[0, "황권", null, 0, null, 75, 59, 88, 0, 160, 300, null, null],
[0, "고유", null, 0, null, 57, 43, 72, 0, 160, 300, null, null],
[0, "고순", null, 0, null, 87, 89, 60, 0, 160, 300, null, null],
[0, "고상", null, 0, null, 68, 68, 53, 0, 160, 300, null, null],
[0, "고승", null, 0, null, 67, 73, 41, 0, 160, 300, null, null],
[0, "후성", null, 0, null, 74, 75, 54, 0, 160, 300, null, null],
[0, "후선", null, 0, null, 63, 66, 34, 0, 160, 300, null, null],
[0, "황조", null, 0, null, 81, 66, 48, 0, 160, 300, null, null],
[0, "공손월", null, 0, null, 74, 72, 47, 0, 160, 300, null, null],
[0, "공손연", null, 0, null, 65, 70, 49, 0, 160, 300, null, null],
[0, "공손공", null, 0, null, 39, 17, 69, 0, 160, 300, null, null],
[0, "공손강", null, 0, null, 72, 66, 46, 0, 160, 300, null, null],
[0, "공손찬", null, 0, null, 86, 82, 62, 0, 160, 300, null, null],
[0, "공손속", null, 0, null, 63, 68, 46, 0, 160, 300, null, null],
[0, "공손도", null, 0, null, 67, 71, 49, 0, 160, 300, null, null],
[0, "공손범", null, 0, null, 73, 69, 49, 0, 160, 300, null, null],
[0, "황충", null, 0, null, 88, 96, 65, 0, 160, 300, null, null],
[0, "고정", null, 0, null, 55, 63, 43, 0, 160, 300, null, null],
[0, "고패", null, 0, null, 66, 48, 69, 0, 160, 300, null, null],
[0, "황보숭", null, 0, null, 91, 61, 82, 0, 160, 300, null, null],
[0, "공융", null, 0, null, 30, 5, 73, 0, 160, 300, null, null],
[0, "고람", null, 0, null, 76, 82, 60, 0, 160, 300, null, null],
[0, "오경", null, 0, null, 69, 66, 45, 0, 160, 300, null, null],
[0, "호거아", null, 0, null, 70, 82, 41, 0, 160, 300, null, null],
[0, "호진", null, 0, null, 65, 74, 12, 0, 160, 300, null, null],
[0, "올돌골", null, 0, null, 79, 86, 11, 0, 160, 300, null, null],
[0, "호반", null, 0, null, 55, 55, 59, 0, 160, 300, null, null],
[0, "오반", null, 0, null, 74, 71, 50, 0, 160, 300, null, null],
[0, "고옹", null, 0, null, 52, 18, 81, 0, 160, 300, null, null],
[0, "오란", null, 0, null, 68, 80, 35, 0, 160, 300, null, null],
[0, "채화", null, 0, null, 39, 50, 1, 0, 160, 300, null, null],
[0, "채중", null, 0, null, 40, 54, 2, 0, 160, 300, null, null],
[0, "채모", null, 0, null, 70, 55, 77, 0, 160, 300, null, null],
[0, "착융", null, 0, null, 60, 69, 38, 0, 160, 300, null, null],
[0, "사마의", null, 0, null, 99, 63, 98, 0, 160, 300, null, null],
[0, "사마염", null, 0, null, 69, 59, 77, 0, 160, 300, null, null],
[0, "사마사", null, 0, null, 84, 64, 89, 0, 160, 300, null, null],
[0, "사마소", null, 0, null, 85, 57, 88, 0, 160, 300, null, null],
[0, "사마부", null, 0, null, 70, 37, 77, 0, 160, 300, null, null],
[0, "사마랑", null, 0, null, 20, 21, 72, 0, 160, 300, null, null],
[0, "사마가", null, 0, null, 66, 84, 25, 0, 160, 300, null, null],
[0, "주흔", null, 0, null, 65, 51, 73, 0, 160, 300, null, null],
[0, "주앙", null, 0, null, 74, 65, 48, 0, 160, 300, null, null],
[0, "주지", null, 0, null, 73, 85, 41, 0, 160, 300, null, null],
[0, "주창", null, 0, null, 68, 77, 42, 0, 160, 300, null, null],
[0, "주태", null, 0, null, 84, 90, 48, 0, 160, 300, null, null],
[0, "주방", null, 0, null, 52, 41, 80, 0, 160, 300, null, null],
[0, "주유", null, 0, null, 97, 71, 97, 0, 160, 300, null, null],
[0, "주환", null, 0, null, 87, 84, 64, 0, 160, 300, null, null],
[0, "주거", null, 0, null, 77, 57, 72, 0, 160, 300, null, null],
[0, "축융", null, 0, null, 72, 75, 35, 0, 160, 300, null, null],
[0, "주준", null, 0, null, 89, 57, 76, 0, 160, 300, null, null],
[0, "주연", null, 0, null, 86, 75, 57, 0, 160, 300, null, null],
[0, "주치", null, 0, null, 71, 56, 72, 0, 160, 300, null, null],
[0, "주포", null, 0, null, 68, 73, 34, 0, 160, 300, null, null],
[0, "주령", null, 0, null, 78, 73, 53, 0, 160, 300, null, null],
[0, "순욱", null, 0, null, 78, 38, 97, 0, 160, 300, null, null],
[0, "순우경", null, 0, null, 78, 66, 29, 0, 160, 300, null, null],
[0, "순심", null, 0, null, 45, 25, 78, 0, 160, 300, null, null],
[0, "순유", null, 0, null, 80, 35, 95, 0, 160, 300, null, null],
[0, "장완", null, 0, null, 78, 34, 89, 0, 160, 300, null, null],
[0, "종회", null, 0, null, 88, 62, 93, 0, 160, 300, null, null],
[0, "장간", null, 0, null, 19, 6, 66, 0, 160, 300, null, null],
[0, "장의거", null, 0, null, 71, 41, 59, 0, 160, 300, null, null],
[0, "장흠", null, 0, null, 78, 85, 54, 0, 160, 300, null, null],
[0, "장제3", null, 0, null, 62, 43, 85, 0, 160, 300, null, null],
[0, "초주", null, 0, null, 16, 3, 67, 0, 160, 300, null, null],
[0, "초촉", null, 0, null, 65, 76, 33, 0, 160, 300, null, null],
[0, "향총", null, 0, null, 76, 56, 77, 0, 160, 300, null, null],
[0, "종요", null, 0, null, 79, 24, 90, 0, 160, 300, null, null],
[0, "향랑", null, 0, null, 28, 18, 74, 0, 160, 300, null, null],
[0, "서영", null, 0, null, 92, 80, 62, 0, 160, 300, null, null],
[0, "제갈각", null, 0, null, 72, 47, 90, 0, 160, 300, null, null],
[0, "제갈근", null, 0, null, 75, 34, 85, 0, 160, 300, null, null],
[0, "제갈균", null, 0, null, 29, 25, 52, 0, 160, 300, null, null],
[0, "제갈탄", null, 0, null, 72, 54, 76, 0, 160, 300, null, null],
[0, "제갈량", null, 0, null, 98, 43, 100, 0, 160, 300, null, null],
[0, "서황", null, 0, null, 95, 94, 74, 0, 160, 300, null, null],
[0, "서서", null, 0, null, 85, 64, 94, 0, 160, 300, null, null],
[0, "서성", null, 0, null, 86, 81, 61, 0, 160, 300, null, null],
[0, "서막", null, 0, null, 55, 32, 68, 0, 160, 300, null, null],
[0, "신의", null, 0, null, 55, 59, 60, 0, 160, 300, null, null],
[0, "신탐", null, 0, null, 56, 62, 54, 0, 160, 300, null, null],
[0, "심배", null, 0, null, 80, 60, 84, 0, 160, 300, null, null],
[0, "신비", null, 0, null, 42, 24, 79, 0, 160, 300, null, null],
[0, "신평", null, 0, null, 69, 43, 77, 0, 160, 300, null, null],
[0, "진복", null, 0, null, 31, 7, 73, 0, 160, 300, null, null],
[0, "진랑", null, 0, null, 58, 70, 35, 0, 160, 300, null, null],
[0, "휴고", null, 0, null, 63, 71, 38, 0, 160, 300, null, null],
[0, "추단", null, 0, null, 61, 64, 34, 0, 160, 300, null, null],
[0, "성의", null, 0, null, 74, 72, 41, 0, 160, 300, null, null],
[0, "성공영", null, 0, null, 73, 58, 80, 0, 160, 300, null, null],
[0, "설종", null, 0, null, 34, 16, 73, 0, 160, 300, null, null],
[0, "단경", null, 0, null, 71, 68, 43, 0, 160, 300, null, null],
[0, "전종", null, 0, null, 78, 55, 75, 0, 160, 300, null, null],
[0, "조예", null, 0, null, 72, 52, 82, 0, 160, 300, null, null],
[0, "조휴", null, 0, null, 84, 78, 58, 0, 160, 300, null, null],
[0, "송헌", null, 0, null, 68, 77, 38, 0, 160, 300, null, null],
[0, "조앙", null, 0, null, 78, 50, 69, 0, 160, 300, null, null],
[0, "조홍", null, 0, null, 80, 75, 55, 0, 160, 300, null, null],
[0, "조순", null, 0, null, 85, 83, 63, 0, 160, 300, null, null],
[0, "조창", null, 0, null, 86, 91, 59, 0, 160, 300, null, null],
[0, "조식", null, 0, null, 45, 22, 86, 0, 160, 300, null, null],
[0, "조진", null, 0, null, 88, 74, 56, 0, 160, 300, null, null],
[0, "조인", null, 0, null, 94, 90, 70, 0, 160, 300, null, null],
[0, "조성", null, 0, null, 54, 74, 38, 0, 160, 300, null, null],
[0, "조조", null, 0, null, 100, 72, 96, 0, 160, 300, null, null, "미망인이 더 매력적이란 말이야... 후후"],
[0, "조충", null, 0, null, 43, 21, 74, 0, 160, 300, null, null],
[0, "장패", null, 0, null, 78, 86, 53, 0, 160, 300, null, null],
[0, "조비", null, 0, null, 75, 64, 87, 0, 160, 300, null, null, "새로운 왕조를 열겠다..."],
[0, "조표", null, 0, null, 54, 69, 32, 0, 160, 300, null, null],
[0, "저수", null, 0, null, 86, 46, 95, 0, 160, 300, null, null],
[0, "소비", null, 0, null, 69, 45, 66, 0, 160, 300, null, null],
[0, "조무", null, 0, null, 70, 71, 50, 0, 160, 300, null, null],
[0, "손환", null, 0, null, 82, 56, 76, 0, 160, 300, null, null],
[0, "손견", null, 0, null, 94, 95, 73, 0, 160, 300, null, null],
[0, "손건", null, 0, null, 44, 33, 79, 0, 160, 300, null, null],
[0, "손권", null, 0, null, 86, 61, 81, 0, 160, 300, null, null],
[0, "손교", null, 0, null, 77, 72, 52, 0, 160, 300, null, null],
[0, "손책", null, 0, null, 93, 94, 74, 0, 160, 300, null, null],
[0, "손소", null, 0, null, 82, 79, 59, 0, 160, 300, null, null],
[0, "손정", null, 0, null, 66, 53, 73, 0, 160, 300, null, null],
[0, "손중", null, 0, null, 62, 71, 36, 0, 160, 300, null, null],
[0, "손등", null, 0, null, 62, 37, 79, 0, 160, 300, null, null],
[0, "손유", null, 0, null, 77, 70, 51, 0, 160, 300, null, null],
[0, "손익", null, 0, null, 67, 83, 27, 0, 160, 300, null, null],
[0, "손례", null, 0, null, 78, 81, 59, 0, 160, 300, null, null],
[0, "태사자", null, 0, null, 94, 94, 72, 0, 160, 300, null, null],
[0, "대래동주", null, 0, null, 51, 53, 54, 0, 160, 300, null, null],
[0, "대릉", null, 0, null, 70, 75, 39, 0, 160, 300, null, null],
[0, "타사대왕", null, 0, null, 62, 48, 70, 0, 160, 300, null, null],
[0, "담웅", null, 0, null, 58, 73, 14, 0, 160, 300, null, null],
[0, "장윤", null, 0, null, 72, 67, 42, 0, 160, 300, null, null],
[0, "조운", null, 0, null, 90, 96, 75, 0, 160, 300, null, null],
[0, "장위", null, 0, null, 74, 66, 45, 0, 160, 300, null, null],
[0, "장영", null, 0, null, 75, 74, 41, 0, 160, 300, null, null],
[0, "장연", null, 0, null, 76, 81, 57, 0, 160, 300, null, null],
[0, "장횡", null, 0, null, 59, 70, 23, 0, 160, 300, null, null],
[0, "장온", null, 0, null, 32, 10, 72, 0, 160, 300, null, null],
[0, "장개", null, 0, null, 34, 66, 8, 0, 160, 300, null, null],
[0, "장각", null, 0, null, 87, 35, 90, 0, 160, 300, null, null],
[0, "장기", null, 0, null, 74, 35, 76, 0, 160, 300, null, null],
[0, "장의", null, 0, null, 79, 55, 75, 0, 160, 300, null, null],
[0, "장훈", null, 0, null, 72, 68, 41, 0, 160, 300, null, null],
[0, "장굉", null, 0, null, 24, 22, 86, 0, 160, 300, null, null],
[0, "장합", null, 0, null, 92, 89, 69, 0, 160, 300, null, null],
[0, "조홍2", null, 0, null, 66, 72, 28, 0, 160, 300, null, null],
[0, "장제2", null, 0, null, 70, 66, 46, 0, 160, 300, null, null],
[0, "장수", null, 0, null, 80, 73, 51, 0, 160, 300, null, null],
[0, "장소", null, 0, null, 41, 13, 87, 0, 160, 300, null, null],
[0, "장송", null, 0, null, 40, 6, 85, 0, 160, 300, null, null],
[0, "장임", null, 0, null, 85, 84, 64, 0, 160, 300, null, null],
[0, "장제", null, 0, null, 67, 43, 80, 0, 160, 300, null, null],
[0, "장막", null, 0, null, 52, 53, 71, 0, 160, 300, null, null],
[0, "조범", null, 0, null, 28, 21, 32, 0, 160, 300, null, null],
[0, "장비", null, 0, null, 87, 98, 72, 0, 160, 300, null, null],
[0, "장포", null, 0, null, 78, 84, 48, 0, 160, 300, null, null],
[0, "장보", null, 0, null, 83, 60, 81, 0, 160, 300, null, null],
[0, "장만성", null, 0, null, 75, 81, 45, 0, 160, 300, null, null],
[0, "장양", null, 0, null, 72, 70, 50, 0, 160, 300, null, null],
[0, "장익", null, 0, null, 75, 55, 76, 0, 160, 300, null, null],
[0, "장료", null, 0, null, 96, 94, 74, 0, 160, 300, null, null],
[0, "장량", null, 0, null, 78, 80, 59, 0, 160, 300, null, null],
[0, "조루", null, 0, null, 70, 43, 68, 0, 160, 300, null, null],
[0, "장로", null, 0, null, 65, 42, 81, 0, 160, 300, null, null],
[0, "진횡", null, 0, null, 64, 63, 26, 0, 160, 300, null, null],
[0, "진응", null, 0, null, 62, 72, 45, 0, 160, 300, null, null],
[0, "진기", null, 0, null, 58, 65, 43, 0, 160, 300, null, null],
[0, "진궁", null, 0, null, 84, 55, 90, 0, 160, 300, null, null],
[0, "진교", null, 0, null, 61, 27, 77, 0, 160, 300, null, null],
[0, "진군", null, 0, null, 32, 14, 75, 0, 160, 300, null, null],
[0, "진규", null, 0, null, 30, 4, 82, 0, 160, 300, null, null],
[0, "진식", null, 0, null, 70, 71, 25, 0, 160, 300, null, null],
[0, "진진", null, 0, null, 46, 46, 69, 0, 160, 300, null, null],
[0, "진태", null, 0, null, 86, 68, 89, 0, 160, 300, null, null],
[0, "진등", null, 0, null, 79, 59, 81, 0, 160, 300, null, null],
[0, "진도", null, 0, null, 82, 78, 58, 0, 160, 300, null, null],
[0, "진무", null, 0, null, 76, 87, 43, 0, 160, 300, null, null],
[0, "진란", null, 0, null, 66, 69, 40, 0, 160, 300, null, null],
[0, "진림", null, 0, null, 25, 9, 75, 0, 160, 300, null, null],
[0, "정욱", null, 0, null, 76, 49, 94, 0, 160, 300, null, null],
[0, "정원지", null, 0, null, 69, 74, 17, 0, 160, 300, null, null],
[0, "정은", null, 0, null, 69, 73, 40, 0, 160, 300, null, null],
[0, "정원", null, 0, null, 70, 76, 35, 0, 160, 300, null, null],
[0, "정보", null, 0, null, 84, 79, 59, 0, 160, 300, null, null],
[0, "정봉", null, 0, null, 81, 92, 69, 0, 160, 300, null, null],
[0, "전위", null, 0, null, 79, 98, 42, 0, 160, 300, null, null],
[0, "전해", null, 0, null, 68, 65, 45, 0, 160, 300, null, null],
[0, "전주", null, 0, null, 66, 51, 73, 0, 160, 300, null, null],
[0, "전풍", null, 0, null, 82, 43, 96, 0, 160, 300, null, null],
[0, "전예", null, 0, null, 93, 85, 66, 0, 160, 300, null, null],
[0, "동윤", null, 0, null, 47, 28, 79, 0, 160, 300, null, null],
[0, "동화", null, 0, null, 57, 34, 75, 0, 160, 300, null, null],
[0, "등애", null, 0, null, 92, 73, 94, 0, 160, 300, null, null],
[0, "도겸", null, 0, null, 51, 27, 64, 0, 160, 300, null, null],
[0, "등현", null, 0, null, 61, 73, 45, 0, 160, 300, null, null],
[0, "등지", null, 0, null, 73, 52, 81, 0, 160, 300, null, null],
[0, "동습", null, 0, null, 72, 85, 50, 0, 160, 300, null, null],
[0, "동승", null, 0, null, 56, 53, 65, 0, 160, 300, null, null],
[0, "동소", null, 0, null, 34, 25, 80, 0, 160, 300, null, null],
[0, "동탁", null, 0, null, 91, 87, 67, 0, 160, 300, null, null],
[0, "동도나", null, 0, null, 68, 73, 31, 0, 160, 300, null, null],
[0, "동민", null, 0, null, 49, 60, 25, 0, 160, 300, null, null],
[0, "등무", null, 0, null, 61, 75, 29, 0, 160, 300, null, null],
[0, "두기", null, 0, null, 74, 43, 78, 0, 160, 300, null, null],
[0, "두예", null, 0, null, 96, 69, 95, 0, 160, 300, null, null],
[0, "배원소", null, 0, null, 49, 65, 25, 0, 160, 300, null, null],
[0, "마완", null, 0, null, 71, 74, 16, 0, 160, 300, null, null],
[0, "마휴", null, 0, null, 68, 73, 48, 0, 160, 300, null, null],
[0, "파재", null, 0, null, 74, 74, 55, 0, 160, 300, null, null],
[0, "마준", null, 0, null, 38, 52, 31, 0, 160, 300, null, null],
[0, "마속", null, 0, null, 61, 59, 84, 0, 160, 300, null, null],
[0, "마대", null, 0, null, 79, 85, 62, 0, 160, 300, null, null],
[0, "마충", null, 0, null, 78, 72, 52, 0, 160, 300, null, null],
[0, "마초", null, 0, null, 86, 97, 44, 0, 160, 300, null, null, "서량의 금마초 나가신다!"],
[0, "마철", null, 0, null, 70, 62, 43, 0, 160, 300, null, null],
[0, "마등", null, 0, null, 85, 80, 52, 0, 160, 300, null, null],
[0, "마량", null, 0, null, 53, 23, 85, 0, 160, 300, null, null],
[0, "반준", null, 0, null, 61, 46, 82, 0, 160, 300, null, null],
[0, "반장", null, 0, null, 76, 80, 59, 0, 160, 300, null, null],
[0, "번조", null, 0, null, 66, 73, 31, 0, 160, 300, null, null],
[0, "번능", null, 0, null, 69, 61, 36, 0, 160, 300, null, null],
[0, "반봉", null, 0, null, 56, 77, 4, 0, 160, 300, null, null],
[0, "비의", null, 0, null, 82, 56, 88, 0, 160, 300, null, null],
[0, "비연", null, 0, null, 60, 66, 21, 0, 160, 300, null, null],
[0, "비시", null, 0, null, 18, 28, 65, 0, 160, 300, null, null],
[0, "미축", null, 0, null, 33, 29, 78, 0, 160, 300, null, null],
[0, "미방", null, 0, null, 54, 61, 32, 0, 160, 300, null, null],
[0, "비요", null, 0, null, 70, 52, 73, 0, 160, 300, null, null],
[0, "무안국", null, 0, null, 70, 79, 34, 0, 160, 300, null, null],
[0, "풍습", null, 0, null, 72, 71, 39, 0, 160, 300, null, null],
[0, "부사인", null, 0, null, 46, 63, 37, 0, 160, 300, null, null],
[0, "부첨", null, 0, null, 73, 85, 62, 0, 160, 300, null, null],
[0, "부손", null, 0, null, 29, 13, 70, 0, 160, 300, null, null],
[0, "문앙", null, 0, null, 76, 96, 65, 0, 160, 300, null, null],
[0, "문흠", null, 0, null, 74, 79, 43, 0, 160, 300, null, null],
[0, "문추", null, 0, null, 87, 95, 49, 0, 160, 300, null, null],
[0, "문빙", null, 0, null, 88, 85, 65, 0, 160, 300, null, null],
[0, "변희", null, 0, null, 56, 70, 62, 0, 160, 300, null, null],
[0, "망아장", null, 0, null, 45, 79, 3, 0, 160, 300, null, null],
[0, "봉기", null, 0, null, 56, 48, 84, 0, 160, 300, null, null],
[0, "방희", null, 0, null, 60, 38, 69, 0, 160, 300, null, null],
[0, "법정", null, 0, null, 82, 47, 94, 0, 160, 300, null, null],
[0, "방통", null, 0, null, 79, 34, 97, 0, 160, 300, null, null],
[0, "방덕", null, 0, null, 89, 94, 70, 0, 160, 300, null, null],
[0, "포륭", null, 0, null, 58, 76, 49, 0, 160, 300, null, null],
[0, "목순", null, 0, null, 52, 77, 11, 0, 160, 300, null, null],
[0, "목록대왕", null, 0, null, 65, 71, 39, 0, 160, 300, null, null],
[0, "보즐", null, 0, null, 83, 51, 81, 0, 160, 300, null, null],
[0, "만총", null, 0, null, 88, 64, 87, 0, 160, 300, null, null],
[0, "모개", null, 0, null, 63, 39, 60, 0, 160, 300, null, null],
[0, "맹획", null, 0, null, 81, 88, 42, 0, 160, 300, null, null],
[0, "맹체", null, 0, null, 75, 55, 75, 0, 160, 300, null, null],
[0, "맹우", null, 0, null, 50, 68, 22, 0, 160, 300, null, null],
[0, "유섭", null, 0, null, 62, 79, 24, 0, 160, 300, null, null],
[0, "양부", null, 0, null, 62, 48, 68, 0, 160, 300, null, null],
[0, "옹개", null, 0, null, 73, 75, 57, 0, 160, 300, null, null],
[0, "양의", null, 0, null, 68, 40, 82, 0, 160, 300, null, null],
[0, "양호", null, 0, null, 94, 69, 92, 0, 160, 300, null, null],
[0, "양홍", null, 0, null, 33, 15, 77, 0, 160, 300, null, null],
[0, "양앙", null, 0, null, 68, 72, 38, 0, 160, 300, null, null],
[0, "양추", null, 0, null, 52, 65, 40, 0, 160, 300, null, null],
[0, "양수", null, 0, null, 46, 23, 83, 0, 160, 300, null, null],
[0, "양추2", null, 0, null, 67, 64, 44, 0, 160, 300, null, null],
[0, "양송", null, 0, null, 17, 5, 28, 0, 160, 300, null, null],
[0, "양임", null, 0, null, 70, 78, 56, 0, 160, 300, null, null],
[0, "양조", null, 0, null, 53, 61, 36, 0, 160, 300, null, null],
[0, "양백", null, 0, null, 44, 45, 19, 0, 160, 300, null, null],
[0, "양부2", null, 0, null, 67, 50, 83, 0, 160, 300, null, null],
[0, "양봉", null, 0, null, 66, 65, 31, 0, 160, 300, null, null],
[0, "양봉2", null, 0, null, 54, 62, 53, 0, 160, 300, null, null],
[0, "뇌동", null, 0, null, 69, 78, 51, 0, 160, 300, null, null],
[0, "뇌박", null, 0, null, 62, 70, 36, 0, 160, 300, null, null],
[0, "이이", null, 0, null, 63, 77, 19, 0, 160, 300, null, null],
[0, "이회", null, 0, null, 79, 58, 79, 0, 160, 300, null, null],
[0, "이각", null, 0, null, 69, 72, 24, 0, 160, 300, null, null],
[0, "육항", null, 0, null, 94, 68, 93, 0, 160, 300, null, null],
[0, "육적", null, 0, null, 20, 7, 72, 0, 160, 300, null, null],
[0, "육손", null, 0, null, 95, 71, 96, 0, 160, 300, null, null],
[0, "이엄", null, 0, null, 83, 84, 63, 0, 160, 300, null, null],
[0, "이유", null, 0, null, 61, 26, 93, 0, 160, 300, null, null],
[0, "이숙", null, 0, null, 46, 69, 61, 0, 160, 300, null, null],
[0, "이통", null, 0, null, 73, 81, 62, 0, 160, 300, null, null],
[0, "이전", null, 0, null, 78, 80, 59, 0, 160, 300, null, null],
[0, "이풍", null, 0, null, 69, 74, 50, 0, 160, 300, null, null],
[0, "유언", null, 0, null, 61, 38, 80, 0, 160, 300, null, null],
[0, "유괴", null, 0, null, 71, 73, 52, 0, 160, 300, null, null],
[0, "유기", null, 0, null, 52, 12, 63, 0, 160, 300, null, null],
[0, "유우", null, 0, null, 62, 33, 75, 0, 160, 300, null, null],
[0, "유훈", null, 0, null, 47, 63, 35, 0, 160, 300, null, null],
[0, "유현", null, 0, null, 54, 66, 51, 0, 160, 300, null, null],
[0, "유순", null, 0, null, 63, 46, 28, 0, 160, 300, null, null],
[0, "유장", null, 0, null, 31, 5, 34, 0, 160, 300, null, null],
[0, "유심", null, 0, null, 60, 48, 70, 0, 160, 300, null, null],
[0, "유선", null, 0, null, 3, 5, 9, 0, 160, 300, null, null],
[0, "유종", null, 0, null, 24, 22, 65, 0, 160, 300, null, null],
[0, "유도", null, 0, null, 25, 23, 26, 0, 160, 300, null, null],
[0, "유파", null, 0, null, 29, 22, 75, 0, 160, 300, null, null],
[0, "유반", null, 0, null, 69, 76, 47, 0, 160, 300, null, null],
[0, "유비", null, 0, null, 88, 78, 59, 0, 160, 300, null, null, "한왕실은 중산정왕의 후손인 내가 이어받겠다...!"],
[0, "유표", null, 0, null, 48, 31, 72, 0, 160, 300, null, null],
[0, "유복", null, 0, null, 64, 49, 74, 0, 160, 300, null, null],
[0, "유벽", null, 0, null, 70, 72, 47, 0, 160, 300, null, null],
[0, "유봉", null, 0, null, 75, 79, 44, 0, 160, 300, null, null],
[0, "유엽", null, 0, null, 56, 32, 92, 0, 160, 300, null, null],
[0, "유요", null, 0, null, 62, 67, 46, 0, 160, 300, null, null],
[0, "여위황", null, 0, null, 58, 63, 29, 0, 160, 300, null, null],
[0, "요화", null, 0, null, 73, 76, 54, 0, 160, 300, null, null],
[0, "양흥", null, 0, null, 61, 65, 19, 0, 160, 300, null, null],
[0, "양습", null, 0, null, 73, 40, 74, 0, 160, 300, null, null],
[0, "양서", null, 0, null, 56, 62, 66, 0, 160, 300, null, null],
[0, "능조", null, 0, null, 75, 81, 42, 0, 160, 300, null, null],
[0, "능통", null, 0, null, 83, 89, 60, 0, 160, 300, null, null],
[0, "여개", null, 0, null, 53, 30, 67, 0, 160, 300, null, null],
[0, "여건", null, 0, null, 57, 70, 62, 0, 160, 300, null, null],
[0, "여광", null, 0, null, 56, 70, 13, 0, 160, 300, null, null],
[0, "여상", null, 0, null, 54, 71, 12, 0, 160, 300, null, null],
[0, "여대", null, 0, null, 80, 71, 52, 0, 160, 300, null, null],
[0, "여범", null, 0, null, 73, 54, 75, 0, 160, 300, null, null],
[0, "여포", null, 0, null, 89, 100, 42, 0, 160, 300, null, null, "다 덤비거라! 하하하하"],
[0, "여몽", null, 0, null, 91, 69, 90, 0, 160, 300, null, null],
[0, "윤직", null, 0, null, 46, 42, 73, 0, 160, 300, null, null],
[0, "냉포", null, 0, null, 71, 82, 61, 0, 160, 300, null, null],
[0, "누규", null, 0, null, 52, 13, 87, 0, 160, 300, null, null],
[0, "노숙", null, 0, null, 89, 56, 93, 0, 160, 300, null, null],
[0, "노식", null, 0, null, 86, 63, 82, 0, 160, 300, null, null],
[0, "범강", null, 0, null, 49, 50, 36, 0, 160, 300, null, null],
[0, "장달", null, 0, null, 43, 56, 34, 0, 160, 300, null, null],
[0, "규람", null, 0, null, 55, 70, 58, 0, 160, 300, null, null],
[0, "대원", null, 0, null, 38, 32, 68, 0, 160, 300, null, null],
[0, "왕기", null, 0, null, 81, 64, 86, 0, 160, 300, null, null],
[0, "왕상", null, 0, null, 23, 19, 68, 0, 160, 300, null, null],
[0, "왕돈", null, 0, null, 60, 66, 46, 0, 160, 300, null, null],
[0, "악침", null, 0, null, 73, 75, 43, 0, 160, 300, null, null],
[0, "하제", null, 0, null, 83, 61, 82, 0, 160, 300, null, null],
[0, "환범", null, 0, null, 40, 11, 78, 0, 160, 300, null, null],
[0, "견초", null, 0, null, 72, 79, 57, 0, 160, 300, null, null],
[0, "고당륭", null, 0, null, 35, 24, 76, 0, 160, 300, null, null],
[0, "오찬", null, 0, null, 68, 41, 78, 0, 160, 300, null, null],
[0, "호질", null, 0, null, 73, 46, 74, 0, 160, 300, null, null],
[0, "오질", null, 0, null, 16, 29, 68, 0, 160, 300, null, null],
[0, "호준", null, 0, null, 79, 76, 55, 0, 160, 300, null, null],
[0, "고담", null, 0, null, 53, 23, 77, 0, 160, 300, null, null],
[0, "최림", null, 0, null, 32, 22, 66, 0, 160, 300, null, null],
[0, "사마망", null, 0, null, 78, 58, 83, 0, 160, 300, null, null],
[0, "주이", null, 0, null, 70, 73, 52, 0, 160, 300, null, null],
[0, "전단", null, 0, null, 67, 64, 39, 0, 160, 300, null, null],
[0, "조우", null, 0, null, 50, 43, 37, 0, 160, 300, null, null],
[0, "조상", null, 0, null, 39, 33, 30, 0, 160, 300, null, null],
[0, "조방", null, 0, null, 20, 14, 27, 0, 160, 300, null, null],
[0, "태사향", null, 0, null, 57, 66, 48, 0, 160, 300, null, null],
[0, "장휴", null, 0, null, 63, 27, 74, 0, 160, 300, null, null],
[0, "장호", null, 0, null, 75, 74, 51, 0, 160, 300, null, null],
[0, "조광", null, 0, null, 67, 71, 53, 0, 160, 300, null, null],
[0, "장집", null, 0, null, 76, 29, 80, 0, 160, 300, null, null],
[0, "장승", null, 0, null, 77, 55, 75, 0, 160, 300, null, null],
[0, "장소2", null, 0, null, 23, 56, 31, 0, 160, 300, null, null],
[0, "조통", null, 0, null, 68, 67, 46, 0, 160, 300, null, null],
[0, "진표", null, 0, null, 66, 42, 74, 0, 160, 300, null, null],
[0, "정무", null, 0, null, 56, 35, 75, 0, 160, 300, null, null],
[0, "정봉2", null, 0, null, 66, 66, 46, 0, 160, 300, null, null],
[0, "전만", null, 0, null, 51, 73, 39, 0, 160, 300, null, null],
[0, "마균", null, 0, null, 22, 17, 71, 0, 160, 300, null, null],
[0, "방회", null, 0, null, 69, 75, 49, 0, 160, 300, null, null],
[0, "낙통", null, 0, null, 76, 58, 75, 0, 160, 300, null, null],
[0, "육개", null, 0, null, 65, 61, 79, 0, 160, 300, null, null],
[0, "유찬", null, 0, null, 78, 81, 59, 0, 160, 300, null, null],
[0, "유소", null, 0, null, 68, 53, 74, 0, 160, 300, null, null],
[0, "요립", null, 0, null, 32, 15, 76, 0, 160, 300, null, null],
[0, "여거", null, 0, null, 78, 51, 71, 0, 160, 300, null, null],
[0, "제갈첨", null, 0, null, 70, 57, 76, 0, 160, 300, null, null],
[0, "손휴", null, 0, null, 57, 42, 78, 0, 160, 300, null, null],
[0, "극정", null, 0, null, 42, 23, 68, 0, 160, 300, null, null],
[0, "호분", null, 0, null, 71, 76, 50, 0, 160, 300, null, null],
[0, "손량", null, 0, null, 32, 26, 70, 0, 160, 300, null, null],
[0, "마막", null, 0, null, 34, 12, 44, 0, 160, 300, null, null],
[0, "손호", null, 0, null, 41, 73, 71, 0, 160, 300, null, null],
[0, "조모", null, 0, null, 54, 61, 59, 0, 160, 300, null, null],
[0, "조환", null, 0, null, 30, 28, 30, 0, 160, 300, null, null],
[0, "사마유", null, 0, null, 71, 54, 75, 0, 160, 300, null, null],
[0, "제갈상", null, 0, null, 64, 79, 62, 0, 160, 300, null, null],
[0, "손화", null, 0, null, 31, 39, 68, 0, 160, 300, null, null],
[0, "염우", null, 0, null, 52, 61, 51, 0, 160, 300, null, null],
[0, "왕경", null, 0, null, 67, 49, 71, 0, 160, 300, null, null],
[0, "왕혼", null, 0, null, 74, 71, 50, 0, 160, 300, null, null],
[0, "곽혁", null, 0, null, 33, 29, 70, 0, 160, 300, null, null],
[0, "가범", null, 0, null, 60, 50, 73, 0, 160, 300, null, null],
[0, "서질", null, 0, null, 68, 83, 24, 0, 160, 300, null, null],
[0, "손준", null, 0, null, 64, 70, 48, 0, 160, 300, null, null],
[0, "손침", null, 0, null, 58, 55, 65, 0, 160, 300, null, null],
[0, "우사", null, 0, null, 61, 34, 74, 0, 160, 300, null, null],
[0, "진건", null, 0, null, 72, 71, 50, 0, 160, 300, null, null],
[0, "동궐", null, 0, null, 65, 59, 76, 0, 160, 300, null, null],
[0, "당자", null, 0, null, 61, 71, 50, 0, 160, 300, null, null],
[0, "등충", null, 0, null, 76, 80, 59, 0, 160, 300, null, null],
[0, "황숭", null, 0, null, 67, 50, 72, 0, 160, 300, null, null],
[0, "화핵", null, 0, null, 20, 24, 71, 0, 160, 300, null, null],
[0, "허의", null, 0, null, 51, 74, 15, 0, 160, 300, null, null],
[0, "송겸", null, 0, null, 66, 78, 42, 0, 160, 300, null, null],
[0, "호제", null, 0, null, 57, 39, 68, 0, 160, 300, null, null],
[0, "나헌", null, 0, null, 86, 62, 82, 0, 160, 300, null, null],
[0, "노숙2", null, 0, null, 73, 53, 74, 0, 160, 300, null, null],
[0, "구성", null, 0, null, 63, 70, 38, 0, 160, 300, null, null],
[0, "어부라", null, 0, null, 72, 68, 21, 0, 160, 300, null, null],
[0, "아하소과", null, 0, null, 61, 76, 13, 0, 160, 300, null, null],
[0, "가비능", null, 0, null, 77, 69, 52, 0, 160, 300, null, null],
[0, "구력거", null, 0, null, 80, 68, 50, 0, 160, 300, null, null],
[0, "강단", null, 0, null, 65, 83, 48, 0, 160, 300, null, null],
[0, "황란", null, 0, null, 63, 75, 44, 0, 160, 300, null, null],
[0, "호주천", null, 0, null, 70, 71, 40, 0, 160, 300, null, null],
[0, "종리목", null, 0, null, 84, 61, 82, 0, 160, 300, null, null],
[0, "제갈교", null, 0, null, 62, 27, 75, 0, 160, 300, null, null],
[0, "답돈", null, 0, null, 84, 82, 61, 0, 160, 300, null, null],
[0, "반임", null, 0, null, 66, 79, 38, 0, 160, 300, null, null],
[0, "보도근", null, 0, null, 64, 73, 50, 0, 160, 300, null, null],
[0, "미당대왕", null, 0, null, 59, 69, 21, 0, 160, 300, null, null],
[0, "유표2", null, 0, null, 73, 74, 48, 0, 160, 300, null, null],
[0, "루반", null, 0, null, 65, 76, 39, 0, 160, 300, null, null],
[0, "손관", null, 0, null, 72, 78, 51, 0, 160, 300, null, null],
[0, "곽석", null, 0, null, 59, 71, 48, 0, 160, 300, null, null],
[0, "주조", null, 0, null, 63, 68, 26, 0, 160, 300, null, null],
[0, "장거", null, 0, null, 79, 75, 56, 0, 160, 300, null, null],
[0, "장순", null, 0, null, 73, 81, 60, 0, 160, 300, null, null],
[0, "철리길", null, 0, null, 77, 70, 52, 0, 160, 300, null, null],
[0, "주삭", null, 0, null, 54, 60, 50, 0, 160, 300, null, null],
[0, "황월영", null, 0, null, 46, 33, 78, 0, 160, 300, null, null],
[0, "채염", null, 0, null, 42, 26, 82, 0, 160, 300, null, null],
[0, "소교", null, 0, null, 23, 15, 78, 0, 160, 300, null, null],
[0, "신헌영", null, 0, null, 65, 35, 90, 0, 160, 300, null, null, "내가 사내로 태어났더라면..."],
[0, "손상향", null, 0, null, 72, 79, 55, 0, 160, 300, null, null],
[0, "대교", null, 0, null, 22, 30, 78, 0, 160, 300, null, null],
[0, "초선", null, 0, null, 12, 22, 71, 0, 160, 300, null, null],
[0, "교모", null, 0, null, 54, 45, 69, 0, 160, 300, null, null],
[0, "관구수", null, 0, null, 58, 62, 33, 0, 160, 300, null, null],
[0, "관구전", null, 0, null, 63, 47, 69, 0, 160, 300, null, null],
[0, "원유", null, 0, null, 56, 40, 73, 0, 160, 300, null, null],
[0, "왕광", null, 0, null, 65, 41, 61, 0, 160, 300, null, null],
[0, "신창", null, 0, null, 50, 26, 42, 0, 160, 300, null, null],
[0, "사마주", null, 0, null, 61, 40, 61, 0, 160, 300, null, null],
[0, "양제", null, 0, null, 67, 49, 71, 0, 160, 300, null, null],
[0, "성만", null, 0, null, 61, 68, 46, 0, 160, 300, null, null],
[0, "오연", null, 0, null, 66, 73, 42, 0, 160, 300, null, null],
[0, "맹충", null, 0, null, 47, 28, 72, 0, 160, 300, null, null],
[0, "잠혼", null, 0, null, 1, 1, 22, 0, 160, 300, null, null],
[0, "사정", null, 0, null, 64, 76, 34, 0, 160, 300, null, null],
[0, "심영", null, 0, null, 70, 77, 55, 0, 160, 300, null, null],
[0, "도준", null, 0, null, 65, 66, 46, 0, 160, 300, null, null],
[0, "만욱", null, 0, null, 21, 25, 71, 0, 160, 300, null, null],
[0, "오언", null, 0, null, 76, 81, 59, 0, 160, 300, null, null],
[0, "위막", null, 0, null, 57, 62, 59, 0, 160, 300, null, null],
[0, "시삭", null, 0, null, 38, 65, 47, 0, 160, 300, null, null],
[0, "전속", null, 0, null, 47, 60, 55, 0, 160, 300, null, null],
[0, "장화", null, 0, null, 36, 27, 78, 0, 160, 300, null, null],
[0, "오거", null, 0, null, 49, 61, 23, 0, 160, 300, null, null],
[0, "추정", null, 0, null, 70, 46, 66, 0, 160, 300, null, null],
[0, "장특", null, 0, null, 73, 54, 75, 0, 160, 300, null, null],
[0, "곽마", null, 0, null, 68, 71, 47, 0, 160, 300, null, null],
[0, "석포", null, 0, null, 69, 71, 49, 0, 160, 300, null, null],
[0, "견홍", null, 0, null, 70, 74, 53, 0, 160, 300, null, null],
[0, "한거자", null, 0, null, 51, 59, 51, 0, 160, 300, null, null],
[0, "휴원진", null, 0, null, 52, 68, 45, 0, 160, 300, null, null],
[0, "곽원", null, 0, null, 66, 73, 36, 0, 160, 300, null, null],
[0, "계옹", null, 0, null, 63, 52, 33, 0, 160, 300, null, null],
[0, "이부", null, 0, null, 31, 36, 74, 0, 160, 300, null, null],
[0, "왕업", null, 0, null, 33, 6, 35, 0, 160, 300, null, null],
[0, "좌혁", null, 0, null, 62, 66, 51, 0, 160, 300, null, null],
[0, "화타", null, 0, null, 57, 25, 73, 0, 160, 300, null, null, "아픈 사람들 모두 내게 오시오~"],
[0, "사마휘", null, 0, null, 55, 26, 82, 0, 160, 300, null, null, "좋지 좋아~"],
[0, "우길", null, 0, null, 23, 15, 90, 0, 160, 300, null, null, "길조로다"],
[0, "헌제", null, 0, null, 22, 18, 68, 0, 160, 300, null, null, "한왕실은 정녕 여기서 끝이란 말인가.."],
[0, "백기", null, 0, null, 100, 88, 69, 0, 160, 300, null, null],
[0, "한신", null, 0, null, 100, 74, 95, 0, 160, 300, null, null],
[0, "악비", null, 0, null, 99, 91, 71, 0, 160, 300, null, null],
[0, "항적", null, 0, null, 99, 100, 65, 0, 160, 300, null, null],
[0, "악의", null, 0, null, 98, 75, 96, 0, 160, 300, null, null],
[0, "영정", null, 0, null, 97, 55, 92, 0, 160, 300, null, null],
[0, "강상", null, 0, null, 94, 49, 100, 0, 160, 300, null, null],
[0, "전단2", null, 0, null, 96, 75, 95, 0, 160, 300, null, null],
[0, "이목", null, 0, null, 96, 69, 88, 0, 160, 300, null, null],
[0, "염파", null, 0, null, 97, 96, 75, 0, 160, 300, null, null],
[0, "왕전", null, 0, null, 94, 64, 83, 0, 160, 300, null, null],
[0, "오기", null, 0, null, 94, 66, 95, 0, 160, 300, null, null],
[0, "곽거병", null, 0, null, 93, 92, 53, 0, 160, 300, null, null],
[0, "영포", null, 0, null, 82, 91, 54, 0, 160, 300, null, null],
[0, "이신", null, 0, null, 81, 88, 63, 0, 160, 300, null, null],
[0, "몽념", null, 0, null, 87, 86, 65, 0, 160, 300, null, null],
[0, "전기", null, 0, null, 80, 85, 44, 0, 160, 300, null, null],
[0, "극신", null, 0, null, 76, 83, 42, 0, 160, 300, null, null],
[0, "항연", null, 0, null, 89, 80, 61, 0, 160, 300, null, null],
[0, "인상여", null, 0, null, 69, 38, 96, 0, 160, 300, null, null],
[0, "장자방", null, 0, null, 72, 40, 100, 0, 160, 300, null, null],
[0, "관이오", null, 0, null, 85, 64, 99, 0, 160, 300, null, null],
[0, "손빈", null, 0, null, 83, 22, 98, 0, 160, 300, null, null],
[0, "소진", null, 0, null, 90, 47, 96, 0, 160, 300, null, null],
[0, "범증", null, 0, null, 68, 24, 94, 0, 160, 300, null, null],
[0, "장의2", null, 0, null, 75, 23, 93, 0, 160, 300, null, null],
[0, "공구", null, 0, null, 68, 70, 91, 0, 160, 300, null, null],
[0, "소하", null, 0, null, 56, 27, 97, 0, 160, 300, null, null],
[0, "한비", null, 0, null, 49, 18, 97, 0, 160, 300, null, null],
[0, "이사", null, 0, null, 48, 24, 95, 0, 160, 300, null, null],
[0, "전문", null, 0, null, 79, 67, 89, 0, 160, 300, null, null],
[0, "황헐", null, 0, null, 81, 68, 88, 0, 160, 300, null, null],
[0, "방난", null, 0, null, 88, 95, 66, 0, 160, 300, null, null],
[0, "개섭", null, 0, null, 43, 97, 54, 0, 160, 300, null, null],
[0, "형가", null, 0, null, 42, 89, 43, 0, 160, 300, null, null],
[0, "유방", null, 0, null, 90, 66, 85, 0, 160, 300, null, null, "나는 사람을 쓰는 재주로 천하를 얻었다"],
[0, "하리", null, 0, null, 100, 100, 72, 0, 160, 300, null, null, "내 업적을 따라올 사람이 있을까?"],
[0, "헹이", null, 0, null, 97, 71, 92, 0, 160, 300, null, null, "맛있다 'ㅅ'"],
[0, "나나", null, 0, null, 96, 67, 87, 0, 160, 300, null, null, "이번 전쟁을 계산해보면 말이죠..."],
[0, "장임2", null, 0, null, 90, 91, 69, 0, 160, 300, null, null, "으리!"],
[0, "하야미", null, 0, null, 94, 73, 95, 0, 160, 300, null, null, "흑막이 되어볼까요"],
[0, "이시리스", null, 0, null, 96, 74, 96, 0, 160, 300, null, null],
[0, "연채홍", null, 0, null, 93, 73, 94, 0, 160, 300, null, null, "엄마도 천통할수 있다!"],
[0, "임사영", null, 0, null, 75, 75, 75, 0, 160, 300, null, null, "일반인 양민입니다"],
[0, "장군보", null, 0, null, 88, 90, 68, 0, 160, 300, null, null],
[0, "크렌스", null, 0, null, 92, 86, 67, 0, 160, 300, null, null],
[0, "콘", null, 0, null, 90, 98, 77, 0, 160, 300, null, null],
[0, "리즈나", null, 0, null, 93, 60, 76, 0, 160, 300, null, null, "내가 다 했다"],
[0, "오티누스", null, 0, null, 93, 93, 73, 0, 160, 300, null, null],
[0, "네시", null, 0, null, 88, 73, 94, 0, 160, 300, null, null, "안 자고 싸우면 이겨요"],
[0, "시뉴카린", null, 0, null, 89, 90, 71, 0, 160, 300, null, null, "흔들흔들"],
[0, "Hide_D", null, 0, null, 39, 99, 75, 0, 160, 300, null, null]
],
"general_ex":[
]
}
+13
View File
@@ -0,0 +1,13 @@
{
"title":"【공백지】 무주공산",
"startYear":180,
"map":{
"mapName":"miniche_clean"
},
"history":[
],
"const": {
"expandCityDefaultCost": 30000,
"expandCityCostCoef": 250
}
}
+1
View File
@@ -152,6 +152,7 @@ CREATE TABLE `general` (
`recturn` VARCHAR(50) NULL DEFAULT '[0,0,0,0]',
`resturn` VARCHAR(30) NULL DEFAULT '',
`penalty` TEXT NULL DEFAULT '',
`aux` TEXT NOT NULL DEFAULT '{}',
PRIMARY KEY (`no`),
INDEX `nation` (`nation`, `npc`),
INDEX `city` (`city`),
+15 -1
View File
@@ -11,9 +11,11 @@
<table class='tb_layout' style='margin:auto;'>
<thead>
<tr><td colspan=11><div style='float:right'><input type='checkbox' id="show_unavailable_troops">불가능한 병종 표시</input></div>
<?php if($commandName=='모병'): ?>
<tr><td align=center colspan=11>모병은 가격 2배의 자금이 소요됩니다.</td></tr>
<div style='text-align:center;'>모병은 가격 2배의 자금이 소요됩니다.</div>
<?php endif; ?>
</td></tr>
<tr>
<td colspan=11 align=center class='bg2'>
현재 기술력 : <?=$techLevelText?>
@@ -43,6 +45,7 @@
<?php foreach($armTypeCrews as $crewObj): ?>
<tr
id="crewType<?=$crewObj->id?>"
class="show_default_<?=$crewObj->showDefault?>"
style='height:64px;background-color:<?=$crewObj->bgcolor?>'
data-rice="<?=$crewObj->baseRice?>"
data-cost="<?=$crewObj->baseCost?>"
@@ -177,5 +180,16 @@ $(function(){
});
$('.btn_fill').click();
$('#show_unavailable_troops').change(function(){
var show = $('#show_unavailable_troops').is(":checked");
if(show){
$('.show_default_false').show();
}
else{
$('.show_default_false').hide();
}
});
$('.show_default_false').hide();
});
</script>
+6 -5
View File
@@ -1,5 +1,6 @@
<span class="obj_tooltip" data-toggle="tooltip" data-placement="top"><?=$text??''?>
<span class="tooltiptext">
<?=$info??''?>
</span>
</span>
<span class="obj_tooltip <?=(isset($copyable_info)&&$copyable_info)?'tooltip_copyable_info':''?>" data-toggle="tooltip" data-placement="top"
><span <?=isset($style)?"style=\"$style\"":''?>><?=$text??''?></span
><span class="tooltiptext"
><span class="hidden_but_copyable">[</span><?=$info??''?><span class="hidden_but_copyable">]</span
></span
></span>
+1 -1
View File
@@ -76,7 +76,7 @@ foreach (AppConf::getList() as $setting) {
'korName' => $serverKorName,
'color' => $serverColor,
'isRoot' => $serverDir == $rootServer,
'lastGitPath' => ($serverGitPath[$serverDir][0])??'origin/master'
'lastGitPath' => ($serverGitPath[$serverDir][0])??($serverDir == $rootServer?'devel':'origin/devel')
];
$server[] = $state;
}
+1 -1
View File
@@ -196,7 +196,7 @@ function postOAuthResult(result){
</div>
</div>
<div id="bottom_box">
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2018 HideD
<div class="container"><a href="terms.2.html">개인정보처리방침</a> &amp; <a href="terms.1.html">이용약관</a><br>© 2020 HideD
<br>크롬과 파이어폭스에 최적화되어있습니다.</div></div>
</div>
+58 -6
View File
@@ -58,12 +58,13 @@ if(!$allowUpdate){
]);
}
$src_target = $storage->$server;
if($src_target){
$src_target = $src_target[0];
}
if(!$allowFullUpdate || !$target){
$target = $storage->$server;
if($target){
$target = $target[0];
}
$target = $src_target;
}
else{
$target = $request['target'];
@@ -114,6 +115,26 @@ if(!file_exists($server)){
if($server == $baseServerName){
exec("git fetch -q 2>&1", $output);
if($output){
Json::die([
'result'=>false,
'reason'=>'git pull 작업 : '.join(', ', $output)
]);
}
if($target != $src_target){
$command = sprintf('git checkout %s -q 2>&1', $target);
exec($command, $output);
if($output){
Json::die([
'result'=>false,
'reason'=>join(', ', $output)
]);
}
}
exec("git pull -q 2>&1", $output);
if($output && $output[0] != 'Already up-to-date.'){
Json::die([
@@ -129,13 +150,44 @@ if($server == $baseServerName){
'verionGit'=>$version
], true
);
if(ServConfig::$imageRequestKey){
try {
$imagePullPath = ServConfig::getImagePullURI();
$pullResult = @file_get_contents($imagePullPath);
if($pullResult === false){
throw new \ErrorException('Invalid URI');
}
$pullResult = Json::decode($pullResult);
if($pullResult['result']){
$imgResult = true;
$imgDetail = $pullResult['version'];
}
else{
$imgResult = false;
$imgDetail = $pullResult['reason'];
}
}
catch(\Exception $e){
$imgResult = false;
$imgDetail = $e->getMessage();
}
}
else{
$imgResult = true;
$imgDetail = 'No key';
}
$storage->$server = [null, $version];
$storage->$server = [$target, $version];
Json::die([
'server'=>$server,
'result'=>true,
'version'=>$version
'version'=>$version,
'imgResult'=>$imgResult,
'imgDetail'=>$imgDetail,
]);
}
+15 -13
View File
@@ -38,22 +38,20 @@ function serverUpdate(caller){
return;
}
if(isRoot){
if(!confirm('서버 라이브러리, 루트 서버에 대해 git pull을 실행합니다.')){
return;
}
}
else if(!allowFullUpdate){
if (!confirm('다음 git tree-ish 주소로 업데이트를 시도합니다 : ' + target)) {
return;
}
}
else {
if(allowFullUpdate){
target = prompt('가져올 git tree-ish 명을 입력해주세요.', target)
if(!target){
return;
}
}
else if(isRoot){
if(!confirm('서버 라이브러리, 루트 서버에 대해 git pull을 실행합니다.')){
return;
}
}
else if (!confirm('다음 git tree-ish 주소로 업데이트를 시도합니다 : ' + target)) {
return;
}
$.ajax({
@@ -66,7 +64,11 @@ function serverUpdate(caller){
}
}).then(function(response) {
if(response.result) {
alert('{0} 서버가 {1} 버전으로 업데이트 되었습니다.'.format(response.server, response.version));
var aux = '';
if(isRoot){
aux = ' (이미지 서버 갱신:{0}, {1})'.format(response.imgResult, response.imgDetail);
}
alert('{0} 서버가 {1} 버전으로 업데이트 되었습니다.{2}'.format(response.server, response.version, aux));
location.reload();
} else {
alert(response.reason);
+2 -1
View File
@@ -99,6 +99,7 @@ function Entrance_drawServerList(serverInfos){
$serverHtml.append(
TemplateEngine(serverReservedTemplate, result.reserved)
);
initTooltip($serverHtml);
return;
}
@@ -149,7 +150,7 @@ function Entrance_drawServerList(serverInfos){
TemplateEngine(serverFullTemplate, {})
);
}
else if(game.npcMode == '가'){
else if(game.npcMode == '가'){
$serverHtml.append(
TemplateEngine(serverCreateAndSelectTemplate, {serverPath:serverPath})
).addClass('server_create_and_select');
+19 -2
View File
@@ -47,6 +47,16 @@ $(document).ready( function () {
$('#serv_host').val(
[location.protocol, '//', location.host, parentPathname].join('')
);
$('#btn_random_generate_key').click(function(){
var token = '';
while(token.length < 24){
token += (Math.random() + 1).toString(36).substring(7);
}
token = token.substr(0,24);
$('#image_request_key').val(token);
});
$('#db_form').validate({
rules:{
db_host:"required",
@@ -56,7 +66,11 @@ $(document).ready( function () {
db_name:"required",
serv_host:"required",
shared_icon_path:"required",
game_image_path:"required"
game_image_path:"required",
image_request_key:{
required:false,
minlength:16
}
},
errorElement: "div",
errorPlacement: function ( error, element ) {
@@ -94,7 +108,10 @@ $(document).ready( function () {
db_name:$('#db_name').val(),
serv_host:$('#serv_host').val(),
shared_icon_path:$('#shared_icon_path').val(),
game_image_path:$('#game_image_path').val()
game_image_path:$('#game_image_path').val(),
image_request_key:$('#image_request_key').val(),
kakao_rest_key:$('#kakao_rest_key').val(),
kakao_admin_key:$('#kakao_admin_key').val(),
}
}).then(function(result){
var deferred = $.Deferred();
+1
View File
@@ -205,6 +205,7 @@ def extractGeneralList(generalSheet, nationList={}, nationChiefInfo={}):
if '환경 변수' in wb.sheet_names():
config = parseConfig(wb.sheet_by_name('환경 변수'))
config['startYear'] -= 3
else:
config = {
'title':'타이틀'
+7 -3
View File
@@ -5,9 +5,11 @@ import time
import glob
import urllib.request
import concurrent.futures
from datetime import datetime
def run(webPath):
print(webPath)
now = datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S"), webPath)
obj = urllib.request.urlopen(webPath)
obj.read()
@@ -44,15 +46,17 @@ def main():
servList.append(webPath)
with concurrent.futures.ThreadPoolExecutor(max_workers=len(servList)) as executor:
with concurrent.futures.ThreadPoolExecutor(max_workers=max(1,len(servList))) as executor:
waiters=[]
for resetPath in autoResetList:
future = executor.submit(run, resetPath)
waiters.append(future)
for _ in range(4):
for idx in range(4):
for webPath in servList:
future = executor.submit(run, webPath)
waiters.append(future)
if idx == 3:
break
time.sleep(15)
for future in waiters:
future.done()
+13 -13
View File
@@ -183,19 +183,19 @@ class StringUtil
}
public static function uniord(string $c) {
if (ord($c{0}) >=0 && ord($c{0}) <= 127)
return ord($c{0});
if (ord($c{0}) >= 192 && ord($c{0}) <= 223)
return (ord($c{0})-192)*64 + (ord($c{1})-128);
if (ord($c{0}) >= 224 && ord($c{0}) <= 239)
return (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128);
if (ord($c{0}) >= 240 && ord($c{0}) <= 247)
return (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128);
if (ord($c{0}) >= 248 && ord($c{0}) <= 251)
return (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128);
if (ord($c{0}) >= 252 && ord($c{0}) <= 253)
return (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128);
if (ord($c{0}) >= 254 && ord($c{0}) <= 255) // error
if (ord($c[0]) >=0 && ord($c[0]) <= 127)
return ord($c[0]);
if (ord($c[0]) >= 192 && ord($c[0]) <= 223)
return (ord($c[0])-192)*64 + (ord($c[1])-128);
if (ord($c[0]) >= 224 && ord($c[0]) <= 239)
return (ord($c[0])-224)*4096 + (ord($c[1])-128)*64 + (ord($c[2])-128);
if (ord($c[0]) >= 240 && ord($c[0]) <= 247)
return (ord($c[0])-240)*262144 + (ord($c[1])-128)*4096 + (ord($c[2])-128)*64 + (ord($c[3])-128);
if (ord($c[0]) >= 248 && ord($c[0]) <= 251)
return (ord($c[0])-248)*16777216 + (ord($c[1])-128)*262144 + (ord($c[2])-128)*4096 + (ord($c[3])-128)*64 + (ord($c[4])-128);
if (ord($c[0]) >= 252 && ord($c[0]) <= 253)
return (ord($c[0])-252)*1073741824 + (ord($c[1])-128)*16777216 + (ord($c[2])-128)*262144 + (ord($c[3])-128)*4096 + (ord($c[4])-128)*64 + (ord($c[5])-128);
if (ord($c[0]) >= 254 && ord($c[0]) <= 255) // error
return FALSE;
return 0;
}
+8 -4
View File
@@ -1,10 +1,14 @@
#!/usr/bin/env sh
dir=$(cd "${0%[/\\]*}" > /dev/null; cd "../leafo/scssphp/bin" && pwd)
dir=$(cd "${0%[/\\]*}" > /dev/null; cd "../scssphp/scssphp/bin" && pwd)
if [ -d /proc/cygdrive ] && [[ $(which php) == $(readlink -n /proc/cygdrive)/* ]]; then
# We are in Cgywin using Windows php, so the path must be translated
dir=$(cygpath -m "$dir");
if [ -d /proc/cygdrive ]; then
case $(which php) in
$(readlink -n /proc/cygdrive)/*)
# We are in Cygwin using Windows php, so the path must be translated
dir=$(cygpath -m "$dir");
;;
esac
fi
"${dir}/pscss" "$@"
+1 -1
View File
@@ -1,4 +1,4 @@
@ECHO OFF
setlocal DISABLEDELAYEDEXPANSION
SET BIN_TARGET=%~dp0/../leafo/scssphp/bin/pscss
SET BIN_TARGET=%~dp0/../scssphp/scssphp/bin/pscss
php "%BIN_TARGET%" %*
+3
View File
@@ -0,0 +1,3 @@
# These are supported funding model platforms
open_collective: medoo
@@ -0,0 +1,19 @@
---
name: Bug report
about: Create a report to help us improve
---
**Describe the bug**
A clear and concise description of what the bug is.
**Information**
- Version of Medoo:
- Type of Database (MySQL, MSSQL, SQLite...):
- System (Liunx\Windows\Mac):
**Detail Code**
The detail code causes the problem.
**Expected output**
A clear and concise description of what output you expected.
+1 -1
View File
@@ -1,6 +1,6 @@
MIT License
Copyright (c) 2018 Angel Lai
Copyright (c) 2019 Angel Lai
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
+6 -4
View File
@@ -6,9 +6,11 @@
<a href="https://packagist.org/packages/catfan/medoo"><img alt="Total Downloads" src="https://poser.pugx.org/catfan/medoo/downloads"></a>
<a href="https://packagist.org/packages/catfan/medoo"><img alt="Latest Stable Version" src="https://poser.pugx.org/catfan/medoo/v/stable"></a>
<a href="https://packagist.org/packages/catfan/medoo"><img alt="License" src="https://poser.pugx.org/catfan/medoo/license"></a>
<a href="https://opencollective.com/medoo"><img alt="Backers on Open Collective" src="https://opencollective.com/Medoo/backers/badge.svg"></a>
<a href="https://opencollective.com/medoo"><img alt="Sponsors on Open Collective" src="https://opencollective.com/Medoo/sponsors/badge.svg"> </a>
</p>
> The Lightest PHP database framework to accelerate development
> The lightweight PHP database framework to accelerate development
## Features
@@ -26,7 +28,7 @@
## Requirement
PHP 5.4+ and PDO extension installed
PHP 5.4+ and PDO extension installed, recommend PHP 7.0+
## Get Started
@@ -34,7 +36,7 @@ PHP 5.4+ and PDO extension installed
Add Medoo to composer.json configuration file.
```
$ composer require catfan/Medoo
$ composer require catfan/medoo
```
And update the composer
@@ -43,7 +45,7 @@ $ composer update
```
```php
// If you installed via composer, just use this code to requrie autoloader on the top of your projects.
// If you installed via composer, just use this code to require autoloader on the top of your projects.
require 'vendor/autoload.php';
// Using Medoo namespace
+4 -4
View File
@@ -1,8 +1,8 @@
{
"name": "catfan/medoo",
"type": "framework",
"description": "The lightest PHP database framework to accelerate development",
"keywords": ["database", "lightweight", "PHP framework", "SQL", "MySQL", "MSSQL", "SQLite", "PostgreSQL", "MariaDB", "Oracle"],
"description": "The lightweight PHP database framework to accelerate development",
"keywords": ["database", "database library", "lightweight", "PHP framework", "SQL", "MySQL", "MSSQL", "SQLite", "PostgreSQL", "MariaDB", "Oracle"],
"homepage": "https://medoo.in",
"license": "MIT",
"support": {
@@ -18,10 +18,10 @@
},
"suggest": {
"ext-pdo_mysql": "For MySQL or MariaDB database",
"ext-pdo_sqlsrv": "For MSSQL database",
"ext-pdo_sqlsrv": "For MSSQL database on both Window/Liunx platform",
"ext-pdo_dblib": "For MSSQL or Sybase database on Linux/UNIX platform",
"ext-pdo_oci": "For Oracle database",
"ext-pdo_oci8": "For Oracle version 8 database",
"ext-pdo_oci8": "For Oracle version 8 database",
"ext-pdo_pqsql": "For PostgreSQL database",
"ext-pdo_sqlite": "For SQLite database"
},
+503 -209
View File
@@ -2,9 +2,9 @@
/*!
* Medoo database framework
* https://medoo.in
* Version 1.5.7
* Version 1.7.8
*
* Copyright 2018, Angel Lai
* Copyright 2019, Angel Lai
* Released under the MIT license
*/
@@ -13,6 +13,7 @@ namespace Medoo;
use PDO;
use Exception;
use PDOException;
use InvalidArgumentException;
class Raw {
public $map;
@@ -29,7 +30,7 @@ class Medoo
protected $statement;
protected $option = [];
protected $dsn;
protected $logs = [];
@@ -39,16 +40,18 @@ class Medoo
protected $guid = 0;
public function __construct($options = null)
{
if (!is_array($options))
{
return false;
}
protected $errorInfo = null;
public function __construct(array $options)
{
if (isset($options[ 'database_type' ]))
{
$this->type = strtolower($options[ 'database_type' ]);
if ($this->type === 'mariadb')
{
$this->type = 'mysql';
}
}
if (isset($options[ 'prefix' ]))
@@ -56,23 +59,47 @@ class Medoo
$this->prefix = $options[ 'prefix' ];
}
if (isset($options[ 'option' ]))
{
$this->option = $options[ 'option' ];
}
if (isset($options[ 'logging' ]) && is_bool($options[ 'logging' ]))
{
$this->logging = $options[ 'logging' ];
}
if (isset($options[ 'command' ]) && is_array($options[ 'command' ]))
$option = isset($options[ 'option' ]) ? $options[ 'option' ] : [];
$commands = (isset($options[ 'command' ]) && is_array($options[ 'command' ])) ? $options[ 'command' ] : [];
switch ($this->type)
{
$commands = $options[ 'command' ];
case 'mysql':
// Make MySQL using standard quoted identifier
$commands[] = 'SET SQL_MODE=ANSI_QUOTES';
break;
case 'mssql':
// Keep MSSQL QUOTED_IDENTIFIER is ON for standard quoting
$commands[] = 'SET QUOTED_IDENTIFIER ON';
// Make ANSI_NULLS is ON for NULL value
$commands[] = 'SET ANSI_NULLS ON';
break;
}
else
if (isset($options[ 'pdo' ]))
{
$commands = [];
if (!$options[ 'pdo' ] instanceof PDO)
{
throw new InvalidArgumentException('Invalid PDO object supplied');
}
$this->pdo = $options[ 'pdo' ];
foreach ($commands as $value)
{
$this->pdo->exec($value);
}
return;
}
if (isset($options[ 'dsn' ]))
@@ -83,7 +110,7 @@ class Medoo
}
else
{
return false;
throw new InvalidArgumentException('Invalid DSN option supplied');
}
}
else
@@ -100,7 +127,6 @@ class Medoo
switch ($this->type)
{
case 'mariadb':
case 'mysql':
$attr = [
'driver' => 'mysql',
@@ -121,8 +147,6 @@ class Medoo
}
}
// Make MySQL using standard quoted identifier
$commands[] = 'SET SQL_MODE=ANSI_QUOTES';
break;
case 'pgsql':
@@ -176,6 +200,16 @@ class Medoo
'host' => $options[ 'server' ] . ($is_port ? ':' . $port : ''),
'dbname' => $options[ 'database_name' ]
];
if (isset($options[ 'appname' ]))
{
$attr[ 'appname' ] = $options[ 'appname' ];
}
if (isset($options[ 'charset' ]))
{
$attr[ 'charset' ] = $options[ 'charset' ];
}
}
else
{
@@ -184,13 +218,46 @@ class Medoo
'Server' => $options[ 'server' ] . ($is_port ? ',' . $port : ''),
'Database' => $options[ 'database_name' ]
];
if (isset($options[ 'appname' ]))
{
$attr[ 'APP' ] = $options[ 'appname' ];
}
$config = [
'ApplicationIntent',
'AttachDBFileName',
'Authentication',
'ColumnEncryption',
'ConnectionPooling',
'Encrypt',
'Failover_Partner',
'KeyStoreAuthentication',
'KeyStorePrincipalId',
'KeyStoreSecret',
'LoginTimeout',
'MultipleActiveResultSets',
'MultiSubnetFailover',
'Scrollable',
'TraceFile',
'TraceOn',
'TransactionIsolation',
'TransparentNetworkIPResolution',
'TrustServerCertificate',
'WSID',
];
foreach ($config as $value)
{
$keyname = strtolower(preg_replace(['/([a-z\d])([A-Z])/', '/([^_])([A-Z][a-z])/'], '$1_$2', $value));
if (isset($options[ $keyname ]))
{
$attr[ $value ] = $options[ $keyname ];
}
}
}
// Keep MSSQL QUOTED_IDENTIFIER is ON for standard quoting
$commands[] = 'SET QUOTED_IDENTIFIER ON';
// Make ANSI_NULLS is ON for NULL value
$commands[] = 'SET ANSI_NULLS ON';
break;
case 'sqlite':
@@ -203,8 +270,18 @@ class Medoo
}
}
if (!isset($attr))
{
throw new InvalidArgumentException('Incorrect connection options');
}
$driver = $attr[ 'driver' ];
if (!in_array($driver, PDO::getAvailableDrivers()))
{
throw new InvalidArgumentException("Unsupported PDO driver: {$driver}");
}
unset($attr[ 'driver' ]);
$stack = [];
@@ -214,22 +291,27 @@ class Medoo
$stack[] = is_int($key) ? $value : $key . '=' . $value;
}
$dsn = $driver . ':' . implode($stack, ';');
$dsn = $driver . ':' . implode(';', $stack);
if (
in_array($this->type, ['mariadb', 'mysql', 'pgsql', 'sybase', 'mssql']) &&
in_array($this->type, ['mysql', 'pgsql', 'sybase', 'mssql']) &&
isset($options[ 'charset' ])
)
{
$commands[] = "SET NAMES '" . $options[ 'charset' ] . "'";
$commands[] = "SET NAMES '{$options[ 'charset' ]}'" . (
$this->type === 'mysql' && isset($options[ 'collation' ]) ?
" COLLATE '{$options[ 'collation' ]}'" : ''
);
}
$this->dsn = $dsn;
try {
$this->pdo = new PDO(
$dsn,
isset($options[ 'username' ]) ? $options[ 'username' ] : null,
isset($options[ 'password' ]) ? $options[ 'password' ] : null,
$this->option
$option
);
foreach ($commands as $value)
@@ -242,18 +324,6 @@ class Medoo
}
}
public function __call($name, $arguments)
{
$aggregation = ['avg', 'count', 'max', 'min', 'sum'];
if (in_array($name, $aggregation))
{
array_unshift($arguments, $name);
return call_user_func_array([$this, 'aggregate'], $arguments);
}
}
public function query($query, $map = [])
{
$raw = $this->raw($query, $map);
@@ -265,6 +335,8 @@ class Medoo
public function exec($query, $map = [])
{
$this->statement = null;
if ($this->debug_mode)
{
echo $this->generate($query, $map);
@@ -285,28 +357,37 @@ class Medoo
$statement = $this->pdo->prepare($query);
if ($statement)
if (!$statement)
{
foreach ($map as $key => $value)
{
$statement->bindValue($key, $value[ 0 ], $value[ 1 ]);
}
$this->errorInfo = $this->pdo->errorInfo();
$this->statement = null;
$statement->execute();
$this->statement = $statement;
return $statement;
return false;
}
return false;
$this->statement = $statement;
foreach ($map as $key => $value)
{
$statement->bindValue($key, $value[ 0 ], $value[ 1 ]);
}
$execute = $statement->execute();
$this->errorInfo = $statement->errorInfo();
if (!$execute)
{
$this->statement = null;
}
return $statement;
}
protected function generate($query, $map)
{
$identifier = [
'mysql' => '`$1`',
'mariadb' => '`$1`',
'mssql' => '[$1]'
];
@@ -396,6 +477,11 @@ class Medoo
protected function tableQuote($table)
{
if (!preg_match('/^[a-zA-Z0-9_]+$/i', $table))
{
throw new InvalidArgumentException("Incorrect table name \"$table\"");
}
return '"' . $this->prefix . $table . '"';
}
@@ -430,6 +516,11 @@ class Medoo
protected function columnQuote($string)
{
if (!preg_match('/^[a-zA-Z0-9_]+(\.?[a-zA-Z0-9_]+)?$/i', $string))
{
throw new InvalidArgumentException("Incorrect column name \"$string\"");
}
if (strpos($string, '.') !== false)
{
return '"' . $this->prefix . str_replace('.', '"."', $string) . '"';
@@ -438,7 +529,7 @@ class Medoo
return '"' . $string . '"';
}
protected function columnPush(&$columns, &$map)
protected function columnPush(&$columns, &$map, $root, $is_join = false)
{
if ($columns === '*')
{
@@ -454,23 +545,34 @@ class Medoo
foreach ($columns as $key => $value)
{
if (is_array($value))
if (!is_int($key) && is_array($value) && $root && count(array_keys($columns)) === 1)
{
$stack[] = $this->columnPush($value, $map);
$stack[] = $this->columnQuote($key);
$stack[] = $this->columnPush($value, $map, false, $is_join);
}
elseif (is_array($value))
{
$stack[] = $this->columnPush($value, $map, false, $is_join);
}
elseif (!is_int($key) && $raw = $this->buildRaw($value, $map))
{
preg_match('/(?<column>[a-zA-Z0-9_\.]+)(\s*\[(?<type>(String|Bool|Int|Number))\])?/i', $key, $match);
$stack[] = $raw . ' AS ' . $this->columnQuote( $match[ 'column' ] );
$stack[] = $raw . ' AS ' . $this->columnQuote($match[ 'column' ]);
}
elseif (is_int($key) && is_string($value))
{
if ($is_join && strpos($value, '*') !== false)
{
throw new InvalidArgumentException('Cannot use table.* to select all columns while joining table');
}
preg_match('/(?<column>[a-zA-Z0-9_\.]+)(?:\s*\((?<alias>[a-zA-Z0-9_]+)\))?(?:\s*\[(?<type>(?:String|Bool|Int|Number|Object|JSON))\])?/i', $value, $match);
if (!empty($match[ 'alias' ]))
{
$stack[] = $this->columnQuote( $match[ 'column' ] ) . ' AS ' . $this->columnQuote( $match[ 'alias' ] );
$stack[] = $this->columnQuote($match[ 'column' ]) . ' AS ' . $this->columnQuote($match[ 'alias' ]);
$columns[ $key ] = $match[ 'alias' ];
@@ -481,12 +583,12 @@ class Medoo
}
else
{
$stack[] = $this->columnQuote( $match[ 'column' ] );
$stack[] = $this->columnQuote($match[ 'column' ]);
}
}
}
return implode($stack, ',');
return implode(',', $stack);
}
protected function arrayQuote($array)
@@ -498,7 +600,7 @@ class Medoo
$stack[] = is_int($value) ? $value : $this->pdo->quote($value);
}
return implode($stack, ',');
return implode(',', $stack);
}
protected function innerConjunct($data, $map, $conjunctor, $outer_conjunctor)
@@ -560,7 +662,7 @@ class Medoo
if (is_numeric($value))
{
$condition .= $map_key;
$map[ $map_key ] = [$value, PDO::PARAM_INT];
$map[ $map_key ] = [$value, is_float($value) ? PDO::PARAM_STR : PDO::PARAM_INT];
}
elseif ($raw = $this->buildRaw($value, $map))
{
@@ -587,8 +689,10 @@ class Medoo
foreach ($value as $index => $item)
{
$placeholders[] = $map_key . $index . '_i';
$map[ $map_key . $index . '_i' ] = $this->typeMap($item, gettype($item));
$stack_key = $map_key . $index . '_i';
$placeholders[] = $stack_key;
$map[ $stack_key ] = $this->typeMap($item, gettype($item));
}
$stack[] = $column . ' NOT IN (' . implode(', ', $placeholders) . ')';
@@ -635,7 +739,7 @@ class Medoo
{
$item = strval($item);
if (!preg_match('/(\[.+\]|_|%.+|.+%)/', $item))
if (!preg_match('/(\[.+\]|[\*\?\!\%#^-_]|%.+|.+%)/', $item))
{
$item = '%' . $item . '%';
}
@@ -682,8 +786,10 @@ class Medoo
foreach ($value as $index => $item)
{
$placeholders[] = $map_key . $index . '_i';
$map[ $map_key . $index . '_i' ] = $this->typeMap($item, gettype($item));
$stack_key = $map_key . $index . '_i';
$placeholders[] = $stack_key;
$map[ $stack_key ] = $this->typeMap($item, gettype($item));
}
$stack[] = $column . ' IN (' . implode(', ', $placeholders) . ')';
@@ -728,7 +834,7 @@ class Medoo
$where_clause = ' WHERE ' . $this->dataImplode($conditions, $map, ' AND');
}
if (isset($where[ 'MATCH' ]))
if (isset($where[ 'MATCH' ]) && $this->type === 'mysql')
{
$MATCH = $where[ 'MATCH' ];
@@ -748,7 +854,7 @@ class Medoo
$mode = ' ' . $mode_array[ $MATCH[ 'mode' ] ];
}
$columns = implode(array_map([$this, 'columnQuote'], $MATCH[ 'columns' ]), ', ');
$columns = implode(', ', array_map([$this, 'columnQuote'], $MATCH[ 'columns' ]));
$map_key = $this->mapKey();
$map[ $map_key ] = [$MATCH[ 'keyword' ], PDO::PARAM_STR];
@@ -769,7 +875,7 @@ class Medoo
$stack[] = $this->columnQuote($value);
}
$where_clause .= ' GROUP BY ' . implode($stack, ',');
$where_clause .= ' GROUP BY ' . implode(',', $stack);
}
elseif ($raw = $this->buildRaw($GROUP, $map))
{
@@ -817,7 +923,7 @@ class Medoo
}
}
$where_clause .= ' ORDER BY ' . implode($stack, ',');
$where_clause .= ' ORDER BY ' . implode(',', $stack);
}
elseif ($raw = $this->buildRaw($ORDER, $map))
{
@@ -894,6 +1000,7 @@ class Medoo
$table_query = $table;
}
$is_join = false;
$join_key = is_array($join) ? array_keys($join) : null;
if (
@@ -901,67 +1008,8 @@ class Medoo
strpos($join_key[ 0 ], '[') === 0
)
{
$table_join = [];
$join_array = [
'>' => 'LEFT',
'<' => 'RIGHT',
'<>' => 'FULL',
'><' => 'INNER'
];
foreach($join as $sub_table => $relation)
{
preg_match('/(\[(?<join>\<\>?|\>\<?)\])?(?<table>[a-zA-Z0-9_]+)\s?(\((?<alias>[a-zA-Z0-9_]+)\))?/', $sub_table, $match);
if ($match[ 'join' ] !== '' && $match[ 'table' ] !== '')
{
if (is_string($relation))
{
$relation = 'USING ("' . $relation . '")';
}
if (is_array($relation))
{
// For ['column1', 'column2']
if (isset($relation[ 0 ]))
{
$relation = 'USING ("' . implode($relation, '", "') . '")';
}
else
{
$joins = [];
foreach ($relation as $key => $value)
{
$joins[] = (
strpos($key, '.') > 0 ?
// For ['tableB.column' => 'column']
$this->columnQuote($key) :
// For ['column1' => 'column2']
$table . '."' . $key . '"'
) .
' = ' .
$this->tableQuote(isset($match[ 'alias' ]) ? $match[ 'alias' ] : $match[ 'table' ]) . '."' . $value . '"';
}
$relation = 'ON ' . implode($joins, ' AND ');
}
}
$table_name = $this->tableQuote($match[ 'table' ]) . ' ';
if (isset($match[ 'alias' ]))
{
$table_name .= 'AS ' . $this->tableQuote($match[ 'alias' ]) . ' ';
}
$table_join[] = $join_array[ $match[ 'join' ] ] . ' JOIN ' . $table_name . $relation;
}
}
$table_query .= ' ' . implode($table_join, ' ');
$is_join = true;
$table_query .= ' ' . $this->buildJoin($table, $join);
}
else
{
@@ -999,6 +1047,10 @@ class Medoo
$where = $columns;
}
}
elseif ($raw = $this->buildRaw($column_fn, $map))
{
$column = $raw;
}
else
{
if (empty($columns) || $this->isRaw($columns))
@@ -1007,18 +1059,83 @@ class Medoo
$where = $join;
}
$column = $column_fn . '(' . $this->columnPush($columns, $map) . ')';
$column = $column_fn . '(' . $this->columnPush($columns, $map, true) . ')';
}
}
else
{
$column = $this->columnPush($columns, $map);
$column = $this->columnPush($columns, $map, true, $is_join);
}
return 'SELECT ' . $column . ' FROM ' . $table_query . $this->whereClause($where, $map);
}
protected function columnMap($columns, &$stack)
protected function buildJoin($table, $join)
{
$table_join = [];
$join_array = [
'>' => 'LEFT',
'<' => 'RIGHT',
'<>' => 'FULL',
'><' => 'INNER'
];
foreach($join as $sub_table => $relation)
{
preg_match('/(\[(?<join>\<\>?|\>\<?)\])?(?<table>[a-zA-Z0-9_]+)\s?(\((?<alias>[a-zA-Z0-9_]+)\))?/', $sub_table, $match);
if ($match[ 'join' ] !== '' && $match[ 'table' ] !== '')
{
if (is_string($relation))
{
$relation = 'USING ("' . $relation . '")';
}
if (is_array($relation))
{
// For ['column1', 'column2']
if (isset($relation[ 0 ]))
{
$relation = 'USING ("' . implode('", "', $relation) . '")';
}
else
{
$joins = [];
foreach ($relation as $key => $value)
{
$joins[] = (
strpos($key, '.') > 0 ?
// For ['tableB.column' => 'column']
$this->columnQuote($key) :
// For ['column1' => 'column2']
$table . '."' . $key . '"'
) .
' = ' .
$this->tableQuote(isset($match[ 'alias' ]) ? $match[ 'alias' ] : $match[ 'table' ]) . '."' . $value . '"';
}
$relation = 'ON ' . implode(' AND ', $joins);
}
}
$table_name = $this->tableQuote($match[ 'table' ]) . ' ';
if (isset($match[ 'alias' ]))
{
$table_name .= 'AS ' . $this->tableQuote($match[ 'alias' ]) . ' ';
}
$table_join[] = $join_array[ $match[ 'join' ] ] . ' JOIN ' . $table_name . $relation;
}
}
return implode(' ', $table_join);
}
protected function columnMap($columns, &$stack, $root)
{
if ($columns === '*')
{
@@ -1061,15 +1178,52 @@ class Medoo
}
elseif (!is_int($key) && is_array($value))
{
$this->columnMap($value, $stack);
if ($root && count(array_keys($columns)) === 1)
{
$stack[ $key ] = [$key, 'String'];
}
$this->columnMap($value, $stack, false);
}
}
return $stack;
}
protected function dataMap($data, $columns, $column_map, &$stack)
protected function dataMap($data, $columns, $column_map, &$stack, $root, &$result)
{
if ($root)
{
$columns_key = array_keys($columns);
if (count($columns_key) === 1 && is_array($columns[$columns_key[0]]))
{
$index_key = array_keys($columns)[0];
$data_key = preg_replace("/^[a-zA-Z0-9_]+\./i", "", $index_key);
$current_stack = [];
foreach ($data as $item)
{
$this->dataMap($data, $columns[ $index_key ], $column_map, $current_stack, false, $result);
$index = $data[ $data_key ];
$result[ $index ] = $current_stack;
}
}
else
{
$current_stack = [];
$this->dataMap($data, $columns, $column_map, $current_stack, false, $result);
$result[] = $current_stack;
}
return;
}
foreach ($columns as $key => $value)
{
$isRaw = $this->isRaw($value);
@@ -1080,7 +1234,7 @@ class Medoo
$column_key = $map[ 0 ];
$result = $data[ $column_key ];
$item = $data[ $column_key ];
if (isset($map[ 1 ]))
{
@@ -1089,7 +1243,7 @@ class Medoo
continue;
}
if (is_null($result))
if (is_null($item))
{
$stack[ $column_key ] = null;
continue;
@@ -1098,50 +1252,103 @@ class Medoo
switch ($map[ 1 ])
{
case 'Number':
$stack[ $column_key ] = (double) $result;
$stack[ $column_key ] = (double) $item;
break;
case 'Int':
$stack[ $column_key ] = (int) $result;
$stack[ $column_key ] = (int) $item;
break;
case 'Bool':
$stack[ $column_key ] = (bool) $result;
$stack[ $column_key ] = (bool) $item;
break;
case 'Object':
$stack[ $column_key ] = unserialize($result);
$stack[ $column_key ] = unserialize($item);
break;
case 'JSON':
$stack[ $column_key ] = json_decode($result, true);
$stack[ $column_key ] = json_decode($item, true);
break;
case 'String':
$stack[ $column_key ] = $result;
$stack[ $column_key ] = $item;
break;
}
}
else
{
$stack[ $column_key ] = $result;
$stack[ $column_key ] = $item;
}
}
else
{
$current_stack = [];
$this->dataMap($data, $value, $column_map, $current_stack);
$this->dataMap($data, $value, $column_map, $current_stack, false, $result);
$stack[ $key ] = $current_stack;
}
}
}
public function create($table, $columns, $options = null)
{
$stack = [];
$tableName = $this->prefix . $table;
foreach ($columns as $name => $definition)
{
if (is_int($name))
{
$stack[] = preg_replace('/\<([a-zA-Z0-9_]+)\>/i', '"$1"', $definition);
}
elseif (is_array($definition))
{
$stack[] = $name . ' ' . implode(' ', $definition);
}
elseif (is_string($definition))
{
$stack[] = $name . ' ' . $this->query($definition);
}
}
$table_option = '';
if (is_array($options))
{
$option_stack = [];
foreach ($options as $key => $value)
{
if (is_string($value) || is_int($value))
{
$option_stack[] = "$key = $value";
}
}
$table_option = ' ' . implode(', ', $option_stack);
}
elseif (is_string($options))
{
$table_option = ' ' . $options;
}
return $this->exec("CREATE TABLE IF NOT EXISTS $tableName (" . implode(', ', $stack) . ")$table_option");
}
public function drop($table)
{
$tableName = $this->prefix . $table;
return $this->exec("DROP TABLE IF EXISTS $tableName");
}
public function select($table, $join, $columns = null, $where = null)
{
$map = [];
$stack = [];
$result = [];
$column_map = [];
$index = 0;
@@ -1152,9 +1359,9 @@ class Medoo
$query = $this->exec($this->selectContext($table, $map, $join, $columns, $where), $map);
$this->columnMap($columns, $column_map);
$this->columnMap($columns, $column_map, true);
if (!$query)
if (!$this->statement)
{
return false;
}
@@ -1164,23 +1371,27 @@ class Medoo
return $query->fetchAll(PDO::FETCH_ASSOC);
}
if ($is_single)
{
return $query->fetchAll(PDO::FETCH_COLUMN);
}
while ($data = $query->fetch(PDO::FETCH_ASSOC))
{
$current_stack = [];
$this->dataMap($data, $columns, $column_map, $current_stack);
$stack[ $index ] = $current_stack;
$index++;
$this->dataMap($data, $columns, $column_map, $current_stack, true, $result);
}
return $stack;
if ($is_single)
{
$single_result = [];
$result_key = $column_map[ $column ][ 0 ];
foreach ($result as $item)
{
$single_result[] = $item[ $result_key ];
}
return $single_result;
}
return $result;
}
public function insert($table, $datas)
@@ -1217,7 +1428,7 @@ class Medoo
continue;
}
$map_key =$this->mapKey();
$map_key = $this->mapKey();
$values[] = $map_key;
@@ -1257,7 +1468,7 @@ class Medoo
}
}
$stack[] = '(' . implode($values, ', ') . ')';
$stack[] = '(' . implode(', ', $values) . ')';
}
foreach ($columns as $key)
@@ -1373,8 +1584,9 @@ class Medoo
public function get($table, $join = null, $columns = null, $where = null)
{
$map = [];
$stack = [];
$result = [];
$column_map = [];
$current_stack = [];
if ($where === null)
{
@@ -1391,33 +1603,31 @@ class Medoo
$query = $this->exec($this->selectContext($table, $map, $join, $columns, $where) . ' LIMIT 1', $map);
if ($query)
if (!$this->statement)
{
$data = $query->fetchAll(PDO::FETCH_ASSOC);
if (isset($data[ 0 ]))
{
if ($column === '*')
{
return $data[ 0 ];
}
$this->columnMap($columns, $column_map);
$this->dataMap($data[ 0 ], $columns, $column_map, $stack);
if ($is_single)
{
return $stack[ $column_map[ $column ][ 0 ] ];
}
return $stack;
}
return false;
}
return false;
$data = $query->fetchAll(PDO::FETCH_ASSOC);
if (isset($data[ 0 ]))
{
if ($column === '*')
{
return $data[ 0 ];
}
$this->columnMap($columns, $column_map, true);
$this->dataMap($data[ 0 ], $columns, $column_map, $current_stack, true, $result);
if ($is_single)
{
return $result[ 0 ][ $column_map[ $column ][ 0 ] ];
}
return $result[ 0 ];
}
}
public function has($table, $join, $where = null)
@@ -1425,16 +1635,66 @@ class Medoo
$map = [];
$column = null;
$query = $this->exec('SELECT EXISTS(' . $this->selectContext($table, $map, $join, $column, $where, 1) . ')', $map);
if ($query)
if ($this->type === 'mssql')
{
$result = $query->fetchColumn();
return $result === '1' || $result === true;
$query = $this->exec($this->selectContext($table, $map, $join, $column, $where, Medoo::raw('TOP 1 1')), $map);
}
else
{
$query = $this->exec('SELECT EXISTS(' . $this->selectContext($table, $map, $join, $column, $where, 1) . ')', $map);
}
return false;
if (!$this->statement)
{
return false;
}
$result = $query->fetchColumn();
return $result === '1' || $result === 1 || $result === true;
}
public function rand($table, $join = null, $columns = null, $where = null)
{
$type = $this->type;
$order = 'RANDOM()';
if ($type === 'mysql')
{
$order = 'RAND()';
}
elseif ($type === 'mssql')
{
$order = 'NEWID()';
}
$order_raw = $this->raw($order);
if ($where === null)
{
if ($columns === null)
{
$columns = [
'ORDER' => $order_raw
];
}
else
{
$column = $join;
unset($columns[ 'ORDER' ]);
$columns[ 'ORDER' ] = $order_raw;
}
}
else
{
unset($where[ 'ORDER' ]);
$where[ 'ORDER' ] = $order_raw;
}
return $this->select($table, $join, $columns, $where);
}
private function aggregate($type, $table, $join = null, $column = null, $where = null)
@@ -1443,14 +1703,39 @@ class Medoo
$query = $this->exec($this->selectContext($table, $map, $join, $column, $where, strtoupper($type)), $map);
if ($query)
if (!$this->statement)
{
$number = $query->fetchColumn();
return is_numeric($number) ? $number + 0 : $number;
return false;
}
return false;
$number = $query->fetchColumn();
return is_numeric($number) ? $number + 0 : $number;
}
public function count($table, $join = null, $column = null, $where = null)
{
return $this->aggregate('count', $table, $join, $column, $where);
}
public function avg($table, $join, $column = null, $where = null)
{
return $this->aggregate('avg', $table, $join, $column, $where);
}
public function max($table, $join, $column = null, $where = null)
{
return $this->aggregate('max', $table, $join, $column, $where);
}
public function min($table, $join, $column = null, $where = null)
{
return $this->aggregate('min', $table, $join, $column, $where);
}
public function sum($table, $join, $column = null, $where = null)
{
return $this->aggregate('sum', $table, $join, $column, $where);
}
public function action($actions)
@@ -1485,22 +1770,30 @@ class Medoo
public function id()
{
if ($this->statement == null)
{
return null;
}
$type = $this->type;
if ($type === 'oracle')
{
return 0;
}
elseif ($type === 'mssql')
{
return $this->pdo->query('SELECT SCOPE_IDENTITY()')->fetchColumn();
}
elseif ($type === 'pgsql')
{
return $this->pdo->query('SELECT LASTVAL()')->fetchColumn();
}
return $this->pdo->lastInsertId();
$lastId = $this->pdo->lastInsertId();
if ($lastId != "0" && $lastId != "")
{
return $lastId;
}
return null;
}
public function debug()
@@ -1512,7 +1805,7 @@ class Medoo
public function error()
{
return $this->statement ? $this->statement->errorInfo() : null;
return $this->errorInfo;
}
public function last()
@@ -1547,7 +1840,8 @@ class Medoo
$output[ $key ] = @$this->pdo->getAttribute(constant('PDO::ATTR_' . $value));
}
$output[ 'dsn' ] = $this->dsn;
return $output;
}
}
?>
}
+2 -2
View File
@@ -279,7 +279,7 @@ class ClassLoader
*/
public function setApcuPrefix($apcuPrefix)
{
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
$this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null;
}
/**
@@ -377,7 +377,7 @@ class ClassLoader
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
$search = $subPath.'\\';
$search = $subPath . '\\';
if (isset($this->prefixDirsPsr4[$search])) {
$pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1);
foreach ($this->prefixDirsPsr4[$search] as $dir) {
+29 -5
View File
@@ -11,14 +11,38 @@ return array(
'DBTransaction' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php',
'FB' => $vendorDir . '/firephp/firephp-core/lib/FirePHPCore/fb.php',
'FirePHP' => $vendorDir . '/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php',
'HTMLPurifier_AttrDef_Float' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/Float.php',
'HTMLPurifier_AttrDef_HTML5_ARel' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/ARel.php',
'HTMLPurifier_AttrDef_HTML5_Datetime' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/Datetime.php',
'HTMLPurifier_AttrDef_HTML5_Duration' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/Duration.php',
'HTMLPurifier_AttrDef_HTML5_Week' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/Week.php',
'HTMLPurifier_AttrDef_HTML5_YearlessDate' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/YearlessDate.php',
'HTMLPurifier_AttrDef_HTML_Bool2' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML/Bool2.php',
'HTMLPurifier_AttrDef_Regexp' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/Regexp.php',
'HTMLPurifier_ChildDef_Details' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Details.php',
'HTMLPurifier_ChildDef_Figure' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Figure.php',
'HTMLPurifier_ChildDef_Media' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Media.php',
'HTMLPurifier_ChildDef_Picture' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Picture.php',
'HTMLPurifier_AttrTransform_HTML5_Dialog' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrTransform/HTML5/Dialog.php',
'HTMLPurifier_AttrTransform_HTML5_Progress' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrTransform/HTML5/Progress.php',
'HTMLPurifier_AttrTransform_HTML5_Script' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrTransform/HTML5/Script.php',
'HTMLPurifier_ChildDef_HTML5_Abstract' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Abstract.php',
'HTMLPurifier_ChildDef_HTML5_Details' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Details.php',
'HTMLPurifier_ChildDef_HTML5_Fieldset' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Fieldset.php',
'HTMLPurifier_ChildDef_HTML5_Figure' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Figure.php',
'HTMLPurifier_ChildDef_HTML5_Media' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Media.php',
'HTMLPurifier_ChildDef_HTML5_Picture' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Picture.php',
'HTMLPurifier_ChildDef_HTML5_Script' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Script.php',
'HTMLPurifier_ChildDef_HTML5_Time' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Time.php',
'HTMLPurifier_HTML5Config' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTML5Config.php',
'HTMLPurifier_HTML5Definition' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTML5Definition.php',
'HTMLPurifier_HTMLModule_HTML5_Bdo' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Bdo.php',
'HTMLPurifier_HTMLModule_HTML5_Edit' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Edit.php',
'HTMLPurifier_HTMLModule_HTML5_Forms' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Forms.php',
'HTMLPurifier_HTMLModule_HTML5_Hypertext' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Hypertext.php',
'HTMLPurifier_HTMLModule_HTML5_Iframe' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Iframe.php',
'HTMLPurifier_HTMLModule_HTML5_Interactive' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Interactive.php',
'HTMLPurifier_HTMLModule_HTML5_List' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/List.php',
'HTMLPurifier_HTMLModule_HTML5_Media' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Media.php',
'HTMLPurifier_HTMLModule_HTML5_Ruby' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Ruby.php',
'HTMLPurifier_HTMLModule_HTML5_SafeScripting' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/SafeScripting.php',
'HTMLPurifier_HTMLModule_HTML5_Scripting' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Scripting.php',
'HTMLPurifier_HTMLModule_HTML5_Text' => $vendorDir . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Text.php',
'MeekroDB' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php',
'MeekroDBEval' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php',
'MeekroDBException' => $vendorDir . '/sergeytsalkov/meekrodb/db.class.php',
+1
View File
@@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);
return array(
'7b11c4dc42b3b3023073cb14e519683c' => $vendorDir . '/ralouphie/getallheaders/src/getallheaders.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'c964ee0ededf28c96ebd9db5099ef910' => $vendorDir . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => $vendorDir . '/guzzlehttp/psr7/src/functions_include.php',
+1 -1
View File
@@ -10,6 +10,7 @@ return array(
'kakao\\' => array($baseDir . '/src/kakao'),
'Valitron\\' => array($vendorDir . '/vlucas/valitron/src/Valitron'),
'Symfony\\Component\\Lock\\' => array($vendorDir . '/symfony/lock'),
'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
'PhpExtended\\Tail\\' => array($vendorDir . '/php-extended/php-tail/src'),
@@ -17,7 +18,6 @@ return array(
'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'),
'Medoo\\' => array($vendorDir . '/catfan/medoo/src'),
'League\\Plates\\' => array($vendorDir . '/league/plates/src'),
'Leafo\\ScssPhp\\' => array($vendorDir . '/leafo/scssphp/src'),
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
+35 -10
View File
@@ -7,6 +7,7 @@ namespace Composer\Autoload;
class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
{
public static $files = array (
'7b11c4dc42b3b3023073cb14e519683c' => __DIR__ . '/..' . '/ralouphie/getallheaders/src/getallheaders.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'c964ee0ededf28c96ebd9db5099ef910' => __DIR__ . '/..' . '/guzzlehttp/promises/src/functions_include.php',
'a0edc8309cc5e1d60e3047b5df6b7052' => __DIR__ . '/..' . '/guzzlehttp/psr7/src/functions_include.php',
@@ -31,6 +32,7 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
'S' =>
array (
'Symfony\\Component\\Lock\\' => 23,
'ScssPhp\\ScssPhp\\' => 16,
),
'P' =>
array (
@@ -47,7 +49,6 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
'L' =>
array (
'League\\Plates\\' => 14,
'Leafo\\ScssPhp\\' => 14,
),
'G' =>
array (
@@ -74,6 +75,10 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
array (
0 => __DIR__ . '/..' . '/symfony/lock',
),
'ScssPhp\\ScssPhp\\' =>
array (
0 => __DIR__ . '/..' . '/scssphp/scssphp/src',
),
'Psr\\Log\\' =>
array (
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
@@ -102,10 +107,6 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
array (
0 => __DIR__ . '/..' . '/league/plates/src',
),
'Leafo\\ScssPhp\\' =>
array (
0 => __DIR__ . '/..' . '/leafo/scssphp/src',
),
'GuzzleHttp\\Psr7\\' =>
array (
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
@@ -143,14 +144,38 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
'DBTransaction' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php',
'FB' => __DIR__ . '/..' . '/firephp/firephp-core/lib/FirePHPCore/fb.php',
'FirePHP' => __DIR__ . '/..' . '/firephp/firephp-core/lib/FirePHPCore/FirePHP.class.php',
'HTMLPurifier_AttrDef_Float' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/Float.php',
'HTMLPurifier_AttrDef_HTML5_ARel' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/ARel.php',
'HTMLPurifier_AttrDef_HTML5_Datetime' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/Datetime.php',
'HTMLPurifier_AttrDef_HTML5_Duration' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/Duration.php',
'HTMLPurifier_AttrDef_HTML5_Week' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/Week.php',
'HTMLPurifier_AttrDef_HTML5_YearlessDate' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML5/YearlessDate.php',
'HTMLPurifier_AttrDef_HTML_Bool2' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/HTML/Bool2.php',
'HTMLPurifier_AttrDef_Regexp' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrDef/Regexp.php',
'HTMLPurifier_ChildDef_Details' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Details.php',
'HTMLPurifier_ChildDef_Figure' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Figure.php',
'HTMLPurifier_ChildDef_Media' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Media.php',
'HTMLPurifier_ChildDef_Picture' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/Picture.php',
'HTMLPurifier_AttrTransform_HTML5_Dialog' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrTransform/HTML5/Dialog.php',
'HTMLPurifier_AttrTransform_HTML5_Progress' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrTransform/HTML5/Progress.php',
'HTMLPurifier_AttrTransform_HTML5_Script' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/AttrTransform/HTML5/Script.php',
'HTMLPurifier_ChildDef_HTML5_Abstract' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Abstract.php',
'HTMLPurifier_ChildDef_HTML5_Details' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Details.php',
'HTMLPurifier_ChildDef_HTML5_Fieldset' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Fieldset.php',
'HTMLPurifier_ChildDef_HTML5_Figure' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Figure.php',
'HTMLPurifier_ChildDef_HTML5_Media' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Media.php',
'HTMLPurifier_ChildDef_HTML5_Picture' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Picture.php',
'HTMLPurifier_ChildDef_HTML5_Script' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Script.php',
'HTMLPurifier_ChildDef_HTML5_Time' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/ChildDef/HTML5/Time.php',
'HTMLPurifier_HTML5Config' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTML5Config.php',
'HTMLPurifier_HTML5Definition' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTML5Definition.php',
'HTMLPurifier_HTMLModule_HTML5_Bdo' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Bdo.php',
'HTMLPurifier_HTMLModule_HTML5_Edit' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Edit.php',
'HTMLPurifier_HTMLModule_HTML5_Forms' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Forms.php',
'HTMLPurifier_HTMLModule_HTML5_Hypertext' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Hypertext.php',
'HTMLPurifier_HTMLModule_HTML5_Iframe' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Iframe.php',
'HTMLPurifier_HTMLModule_HTML5_Interactive' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Interactive.php',
'HTMLPurifier_HTMLModule_HTML5_List' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/List.php',
'HTMLPurifier_HTMLModule_HTML5_Media' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Media.php',
'HTMLPurifier_HTMLModule_HTML5_Ruby' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Ruby.php',
'HTMLPurifier_HTMLModule_HTML5_SafeScripting' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/SafeScripting.php',
'HTMLPurifier_HTMLModule_HTML5_Scripting' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Scripting.php',
'HTMLPurifier_HTMLModule_HTML5_Text' => __DIR__ . '/..' . '/xemlock/htmlpurifier-html5/library/HTMLPurifier/HTMLModule/HTML5/Text.php',
'MeekroDB' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php',
'MeekroDBEval' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php',
'MeekroDBException' => __DIR__ . '/..' . '/sergeytsalkov/meekrodb/db.class.php',
+207 -131
View File
@@ -49,17 +49,17 @@
},
{
"name": "catfan/medoo",
"version": "v1.5.7",
"version_normalized": "1.5.7.0",
"version": "v1.7.8",
"version_normalized": "1.7.8.0",
"source": {
"type": "git",
"url": "https://github.com/catfan/Medoo.git",
"reference": "8d90cba0e8ff176028847527d0ea76fe41a06ecf"
"reference": "dd9d570584cfb1e09ec470608479b86e41d5b60d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/catfan/Medoo/zipball/8d90cba0e8ff176028847527d0ea76fe41a06ecf",
"reference": "8d90cba0e8ff176028847527d0ea76fe41a06ecf",
"url": "https://api.github.com/repos/catfan/Medoo/zipball/dd9d570584cfb1e09ec470608479b86e41d5b60d",
"reference": "dd9d570584cfb1e09ec470608479b86e41d5b60d",
"shasum": ""
},
"require": {
@@ -73,9 +73,9 @@
"ext-pdo_oci8": "For Oracle version 8 database",
"ext-pdo_pqsql": "For PostgreSQL database",
"ext-pdo_sqlite": "For SQLite database",
"ext-pdo_sqlsrv": "For MSSQL database"
"ext-pdo_sqlsrv": "For MSSQL database on both Window/Liunx platform"
},
"time": "2018-06-14T18:59:08+00:00",
"time": "2019-12-19T05:04:34+00:00",
"type": "framework",
"installation-source": "dist",
"autoload": {
@@ -93,10 +93,11 @@
"email": "angel@catfan.me"
}
],
"description": "The lightest PHP database framework to accelerate development",
"description": "The lightweight PHP database framework to accelerate development",
"homepage": "https://medoo.in",
"keywords": [
"database",
"database library",
"lightweight",
"mariadb",
"mssql",
@@ -110,26 +111,26 @@
},
{
"name": "ezyang/htmlpurifier",
"version": "v4.10.0",
"version_normalized": "4.10.0.0",
"version": "v4.12.0",
"version_normalized": "4.12.0.0",
"source": {
"type": "git",
"url": "https://github.com/ezyang/htmlpurifier.git",
"reference": "d85d39da4576a6934b72480be6978fb10c860021"
"reference": "a617e55bc62a87eec73bd456d146d134ad716f03"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/d85d39da4576a6934b72480be6978fb10c860021",
"reference": "d85d39da4576a6934b72480be6978fb10c860021",
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/a617e55bc62a87eec73bd456d146d134ad716f03",
"reference": "a617e55bc62a87eec73bd456d146d134ad716f03",
"shasum": ""
},
"require": {
"php": ">=5.2"
},
"require-dev": {
"simpletest/simpletest": "^1.1"
"simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
},
"time": "2018-02-23T01:58:20+00:00",
"time": "2019-10-28T03:44:26+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -142,7 +143,7 @@
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"LGPL"
"LGPL-2.1-or-later"
],
"authors": [
{
@@ -197,47 +198,49 @@
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
"version_normalized": "6.3.3.0",
"version": "6.5.2",
"version_normalized": "6.5.2.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/guzzle.git",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba"
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"reference": "407b0cb880ace85c9b63c5f9551db498cb2d50ba",
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/43ece0e75098b7ecd8d13918293029e555a50f82",
"reference": "43ece0e75098b7ecd8d13918293029e555a50f82",
"shasum": ""
},
"require": {
"ext-json": "*",
"guzzlehttp/promises": "^1.0",
"guzzlehttp/psr7": "^1.4",
"guzzlehttp/psr7": "^1.6.1",
"php": ">=5.5"
},
"require-dev": {
"ext-curl": "*",
"phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0",
"psr/log": "^1.0"
"psr/log": "^1.1"
},
"suggest": {
"ext-intl": "Required for Internationalized Domain Name (IDN) support",
"psr/log": "Required for using the Log middleware"
},
"time": "2018-04-22T15:46:56+00:00",
"time": "2019-12-23T11:57:10+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "6.3-dev"
"dev-master": "6.5-dev"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"src/functions_include.php"
],
"psr-4": {
"GuzzleHttp\\": "src/"
}
},
"files": [
"src/functions_include.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
@@ -317,34 +320,39 @@
},
{
"name": "guzzlehttp/psr7",
"version": "1.4.2",
"version_normalized": "1.4.2.0",
"version": "1.6.1",
"version_normalized": "1.6.1.0",
"source": {
"type": "git",
"url": "https://github.com/guzzle/psr7.git",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c"
"reference": "239400de7a173fe9901b9ac7c06497751f00727a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/239400de7a173fe9901b9ac7c06497751f00727a",
"reference": "239400de7a173fe9901b9ac7c06497751f00727a",
"shasum": ""
},
"require": {
"php": ">=5.4.0",
"psr/http-message": "~1.0"
"psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5 || ^3.0.0"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
"ext-zlib": "*",
"phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
},
"time": "2017-03-20T17:10:46+00:00",
"suggest": {
"zendframework/zend-httphandlerrunner": "Emit PSR-7 responses"
},
"time": "2019-07-01T23:21:34+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
"dev-master": "1.6-dev"
}
},
"installation-source": "dist",
@@ -375,6 +383,7 @@
"keywords": [
"http",
"message",
"psr-7",
"request",
"response",
"stream",
@@ -382,60 +391,6 @@
"url"
]
},
{
"name": "leafo/scssphp",
"version": "v0.7.7",
"version_normalized": "0.7.7.0",
"source": {
"type": "git",
"url": "https://github.com/leafo/scssphp.git",
"reference": "1d656f8c02a3a69404bba6b28ec4e06edddf0f49"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/leafo/scssphp/zipball/1d656f8c02a3a69404bba6b28ec4e06edddf0f49",
"reference": "1d656f8c02a3a69404bba6b28ec4e06edddf0f49",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "~4.6",
"squizlabs/php_codesniffer": "~2.5"
},
"time": "2018-07-22T01:22:08+00:00",
"bin": [
"bin/pscss"
],
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"Leafo\\ScssPhp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Leaf Corcoran",
"email": "leafot@gmail.com",
"homepage": "http://leafo.net"
}
],
"description": "scssphp is a compiler for SCSS written in PHP.",
"homepage": "http://leafo.github.io/scssphp/",
"keywords": [
"css",
"less",
"sass",
"scss",
"stylesheet"
]
},
{
"name": "league/plates",
"version": "3.3.0",
@@ -495,17 +450,17 @@
},
{
"name": "monolog/monolog",
"version": "1.23.0",
"version_normalized": "1.23.0.0",
"version": "1.25.3",
"version_normalized": "1.25.3.0",
"source": {
"type": "git",
"url": "https://github.com/Seldaek/monolog.git",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
"reference": "fa82921994db851a8becaf3787a9e73c5976b6f1"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fa82921994db851a8becaf3787a9e73c5976b6f1",
"reference": "fa82921994db851a8becaf3787a9e73c5976b6f1",
"shasum": ""
},
"require": {
@@ -541,7 +496,7 @@
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
"sentry/sentry": "Allow sending log messages to a Sentry server"
},
"time": "2017-06-19T01:22:40+00:00",
"time": "2019-12-20T14:15:16+00:00",
"type": "library",
"extra": {
"branch-alias": {
@@ -741,27 +696,27 @@
},
{
"name": "psr/log",
"version": "1.0.2",
"version_normalized": "1.0.2.0",
"version": "1.1.2",
"version_normalized": "1.1.2.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
"url": "https://api.github.com/repos/php-fig/log/zipball/446d54b4cb6bf489fc9d75f55843658e6f25d801",
"reference": "446d54b4cb6bf489fc9d75f55843658e6f25d801",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"time": "2016-10-10T12:19:37+00:00",
"time": "2019-11-01T11:05:21+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
"dev-master": "1.1.x-dev"
}
},
"installation-source": "dist",
@@ -788,6 +743,111 @@
"psr-3"
]
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"version_normalized": "3.0.3.0",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"time": "2019-03-08T08:55:37+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders."
},
{
"name": "scssphp/scssphp",
"version": "1.0.6",
"version_normalized": "1.0.6.0",
"source": {
"type": "git",
"url": "https://github.com/scssphp/scssphp.git",
"reference": "5b3c9d704950d8f9637f5110c36c281ec47dc13c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/scssphp/scssphp/zipball/5b3c9d704950d8f9637f5110c36c281ec47dc13c",
"reference": "5b3c9d704950d8f9637f5110c36c281ec47dc13c",
"shasum": ""
},
"require": {
"ext-ctype": "*",
"ext-json": "*",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.3",
"squizlabs/php_codesniffer": "~2.5",
"twbs/bootstrap": "~4.3",
"zurb/foundation": "~6.5"
},
"time": "2019-12-12T05:00:52+00:00",
"bin": [
"bin/pscss"
],
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"ScssPhp\\ScssPhp\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Anthon Pang",
"email": "apang@softwaredevelopment.ca",
"homepage": "https://github.com/robocoder"
},
{
"name": "Cédric Morin",
"email": "cedric@yterium.com",
"homepage": "https://github.com/Cerdic"
}
],
"description": "scssphp is a compiler for SCSS written in PHP.",
"homepage": "http://scssphp.github.io/scssphp/",
"keywords": [
"css",
"less",
"sass",
"scss",
"stylesheet"
]
},
{
"name": "sergeytsalkov/meekrodb",
"version": "v2.3",
@@ -835,31 +895,36 @@
},
{
"name": "symfony/lock",
"version": "v4.1.1",
"version_normalized": "4.1.1.0",
"version": "v4.4.3",
"version_normalized": "4.4.3.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/lock.git",
"reference": "d508b5dd92272cb74300396ecaadde969d0f7976"
"reference": "6c4f5b620871cfef5b004fc57f2ca74572ae03b3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/lock/zipball/d508b5dd92272cb74300396ecaadde969d0f7976",
"reference": "d508b5dd92272cb74300396ecaadde969d0f7976",
"url": "https://api.github.com/repos/symfony/lock/zipball/6c4f5b620871cfef5b004fc57f2ca74572ae03b3",
"reference": "6c4f5b620871cfef5b004fc57f2ca74572ae03b3",
"shasum": ""
},
"require": {
"php": "^7.1.3",
"psr/log": "~1.0"
},
"conflict": {
"doctrine/dbal": "<2.5"
},
"require-dev": {
"doctrine/dbal": "~2.5",
"mongodb/mongodb": "~1.1",
"predis/predis": "~1.0"
},
"time": "2018-06-21T11:15:46+00:00",
"time": "2020-01-04T13:00:46+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
"dev-master": "4.4-dev"
}
},
"installation-source": "dist",
@@ -876,13 +941,13 @@
"MIT"
],
"authors": [
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
},
{
"name": "Jérémy Derussé",
"email": "jeremy@derusse.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony Lock Component",
@@ -898,17 +963,17 @@
},
{
"name": "vlucas/valitron",
"version": "v1.4.3",
"version_normalized": "1.4.3.0",
"version": "v1.4.7",
"version_normalized": "1.4.7.0",
"source": {
"type": "git",
"url": "https://github.com/vlucas/valitron.git",
"reference": "3c5463315bfa23b17f8949b100a960d035234e43"
"reference": "a03072bed1679660200766d134507a30193eaf6d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/vlucas/valitron/zipball/3c5463315bfa23b17f8949b100a960d035234e43",
"reference": "3c5463315bfa23b17f8949b100a960d035234e43",
"url": "https://api.github.com/repos/vlucas/valitron/zipball/a03072bed1679660200766d134507a30193eaf6d",
"reference": "a03072bed1679660200766d134507a30193eaf6d",
"shasum": ""
},
"require": {
@@ -920,7 +985,7 @@
"suggest": {
"ext-mbstring": "It can support the multiple bytes string length."
},
"time": "2018-05-06T10:45:26+00:00",
"time": "2019-08-29T19:49:43+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -949,27 +1014,28 @@
},
{
"name": "xemlock/htmlpurifier-html5",
"version": "v0.1.7",
"version_normalized": "0.1.7.0",
"version": "v0.1.11",
"version_normalized": "0.1.11.0",
"source": {
"type": "git",
"url": "https://github.com/xemlock/htmlpurifier-html5.git",
"reference": "b4b35e51ec75e0207c23035f7d9a354bdcdac359"
"reference": "f0d563f9fd4a82a3d759043483f9a94c0d8c2255"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/xemlock/htmlpurifier-html5/zipball/b4b35e51ec75e0207c23035f7d9a354bdcdac359",
"reference": "b4b35e51ec75e0207c23035f7d9a354bdcdac359",
"url": "https://api.github.com/repos/xemlock/htmlpurifier-html5/zipball/f0d563f9fd4a82a3d759043483f9a94c0d8c2255",
"reference": "f0d563f9fd4a82a3d759043483f9a94c0d8c2255",
"shasum": ""
},
"require": {
"ezyang/htmlpurifier": "^4.7",
"ezyang/htmlpurifier": "^4.8",
"php": ">=5.2"
},
"require-dev": {
"phpunit/phpunit": "4.7.*|5.7.*"
"php-coveralls/php-coveralls": "^1.1|^2.1",
"phpunit/phpunit": ">=4.7 <8.0"
},
"time": "2018-06-07T14:30:17+00:00",
"time": "2019-08-07T17:19:21+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
@@ -987,6 +1053,16 @@
"email": "xemlock@gmail.com"
}
],
"description": "HTML Purifier definitions for HTML5 elements"
"description": "HTML5 element definitions for HTML Purifier",
"keywords": [
"HTML5",
"Purifier",
"html",
"htmlpurifier",
"security",
"tidy",
"validator",
"xss"
]
}
]
+2 -34
View File
@@ -15,7 +15,7 @@ with these contents.
---------------------------------------------------------------------------
1. Compatibility
HTML Purifier is PHP 5 and PHP 7, and is actively tested from PHP 5.0.5
HTML Purifier is PHP 5 and PHP 7, and is actively tested from PHP 5.3
and up. It has no core dependencies with other libraries.
These optional extensions can enhance the capabilities of HTML Purifier:
@@ -101,31 +101,6 @@ Autoload compatibility
autoloader, but there are some cases where you will need to change
your own code to accomodate HTML Purifier. These are those cases:
PHP VERSION IS LESS THAN 5.1.2, AND YOU'VE DEFINED __autoload
Because spl_autoload_register() doesn't exist in early versions
of PHP 5, HTML Purifier has no way of adding itself to the autoload
stack. Modify your __autoload function to test
HTMLPurifier_Bootstrap::autoload($class)
For example, suppose your autoload function looks like this:
function __autoload($class) {
require str_replace('_', '/', $class) . '.php';
return true;
}
A modified version with HTML Purifier would look like this:
function __autoload($class) {
if (HTMLPurifier_Bootstrap::autoload($class)) return true;
require str_replace('_', '/', $class) . '.php';
return true;
}
Note that there *is* some custom behavior in our autoloader; the
original autoloader in our example would work for 99% of the time,
but would fail when including language files.
AN __autoload FUNCTION IS DECLARED AFTER OUR AUTOLOADER IS REGISTERED
spl_autoload_register() has the curious behavior of disabling
the existing __autoload() handler. Users need to explicitly
@@ -138,11 +113,6 @@ Autoload compatibility
spl_autoload_register('__autoload')
Users should also be on guard if they use a version of PHP previous
to 5.1.2 without an autoloader--HTML Purifier will define __autoload()
for you, which can collide with an autoloader that was added by *you*
later.
For better performance
----------------------
@@ -204,9 +174,7 @@ For advanced users
HTMLPurifier.autoload.php
Registers our autoload handler HTMLPurifier_Bootstrap::autoload($class).
You can do these operations by yourself--in fact, you must modify your own
autoload handler if you are using a version of PHP earlier than PHP 5.1.2
(See "Autoload compatibility" above).
You can do these operations by yourself, if you like.
---------------------------------------------------------------------------
+1 -1
View File
@@ -11,7 +11,7 @@ pied de page, mais je recommande de lire le document.
1. Compatibilité
HTML Purifier fonctionne avec PHP 5. PHP 5.0.5 est la dernière version testée.
HTML Purifier fonctionne avec PHP 5. PHP 5.3 est la dernière version testée.
Il ne dépend pas d'autres librairies.
Les extensions optionnelles sont iconv (généralement déjà installée) et tidy
+34
View File
@@ -9,6 +9,40 @@ NEWS ( CHANGELOG and HISTORY ) HTMLPurifier
. Internal change
==========================
4.12.0, released 2019-10-27
! PHP 7.4 is supported, thank you Witold Wasiczko, Mateuz Turcza and
Edi Modrić
- PHPDocs for HTMLModule::addElement() and Bool attr are fixed (thanks
Mateusz)
4.11.0, released 2019-07-14
# SafeScripting now matches case-sensitively against its whitelist (previously it was
case-insensitive.) Thanks Dimitri Gritsajuk <gritsajuk.dimitri@gmail.com>
for reporting.
! New directive %Core.AllowParseManyTags which allows parsing of many nested tags.
Thanks M. Suzuki <msuzuki1986@gmail.com> for contributing the patch.
! purifyArray now supports multidimensional arrays. Thanks
Sandro Miguel Marques <sandromiguel@sandromiguel.com> for contributing this patch.
! initial and inherit settings available for width, height, and the min-/max-
versions thereof. Thanks Michael Kliewe <info@phpgansta.de> for contributing
this patch.
! More color names are supported. Thanks Daijobou for contributing.
- Compatibility fixes for PHP 7.3, including new CI for PHP 7.3
(thank you Lukas Neumann <lksnmnn@gmail.com>) and removal of
reserved words in our constants (thanks Darko Hrgovic <darko@darkodev.com>
- Compatibility fixes for HHVM. Thanks Mateusz Turcza for contributing
this fix.
- HTML Purifier now never defines __autoload, fixing #196. Thanks
Michael Kliewe for reporting.
- In some situations, Config.php would report an undefined index: class
error; this has been fixed. Thanks DiLong Fa for contributing
this fix.
- We no longer produce <script /> tags; we always explicitly write
out the open and close tag. Thanks Dimitri Gritsajuk
<gritsajuk.dimitri@gmail.com> for contributing this fix.
- Better compatibility when IDNA constants are not present. Thanks
Mateusz Turcza <xemlock@gmail.com> for contributing this fix.
4.10.0, released 2018-02-22
# PHP 5.3 is no longer officially supported by HTML Purifier
(we did not specifically break support, but we are no longer
+1 -1
View File
@@ -26,4 +26,4 @@ Package available on [Composer](https://packagist.org/packages/ezyang/htmlpurifi
If you're using Composer to manage dependencies, you can use
$ composer require "ezyang/htmlpurifier":"dev-master"
$ composer require ezyang/htmlpurifier
+1 -1
View File
@@ -1 +1 @@
4.10.0
4.12.0
+2 -13
View File
@@ -1,13 +1,2 @@
HTML Purifier 4.9.x is a maintenance release, collecting a year
of accumulated bug fixes plus a few new features. New features
include support for min/max-width/height CSS, and rgba/hsl/hsla
in color specifications. Major bugfixes include improvements
in the Serializer cache to avoid chmod'ing directories, better
entity decoding (we won't accidentally encode entities that occur
in URLs) and rel="noopener" on links with target attributes,
to prevent them from overwriting the original frame.
4.9.3 works around an infinite loop bug in PHP 7.1 with the opcode
cache (and has one other, minor bugfix, avoiding using autoloading
when testing for DOMDocument presence). If these bugs do not
affect you, you do not need to upgrade.
HTML Purifier 4.12.x is a maintenance release which makes
compatibility fixes for PHP 7.4.
+2 -2
View File
@@ -4,7 +4,7 @@
"type": "library",
"keywords": ["html"],
"homepage": "http://htmlpurifier.org/",
"license": "LGPL",
"license": "LGPL-2.1-or-later",
"authors": [
{
"name": "Edward Z. Yang",
@@ -16,7 +16,7 @@
"php": ">=5.2"
},
"require-dev": {
"simpletest/simpletest": "^1.1"
"simpletest/simpletest": "dev-master#72de02a7b80c6bb8864ef9bf66d41d2f58f826bd"
},
"autoload": {
"psr-0": { "HTMLPurifier": "library/" },
@@ -7,7 +7,7 @@
* primary concern and you are using an opcode cache. PLEASE DO NOT EDIT THIS
* FILE, changes will be overwritten the next time the script is run.
*
* @version 4.10.0
* @version 4.12.0
*
* @warning
* You must *not* include any other HTML Purifier files before this file,
+10 -6
View File
@@ -19,7 +19,7 @@
*/
/*
HTML Purifier 4.10.0 - Standards Compliant HTML Filtering
HTML Purifier 4.12.0 - Standards Compliant HTML Filtering
Copyright (C) 2006-2008 Edward Z. Yang
This library is free software; you can redistribute it and/or
@@ -58,12 +58,12 @@ class HTMLPurifier
* Version of HTML Purifier.
* @type string
*/
public $version = '4.10.0';
public $version = '4.12.0';
/**
* Constant with version of HTML Purifier.
*/
const VERSION = '4.10.0';
const VERSION = '4.12.0';
/**
* Global configuration object.
@@ -240,12 +240,16 @@ class HTMLPurifier
public function purifyArray($array_of_html, $config = null)
{
$context_array = array();
foreach ($array_of_html as $key => $html) {
$array_of_html[$key] = $this->purify($html, $config);
foreach($array_of_html as $key=>$value){
if (is_array($value)) {
$array[$key] = $this->purifyArray($value, $config);
} else {
$array[$key] = $this->purify($value, $config);
}
$context_array[$key] = $this->context;
}
$this->context = $context_array;
return $array_of_html;
return $array;
}
/**
@@ -7,7 +7,7 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
{
/**
* @type bool
* @type string
*/
protected $name;
@@ -17,7 +17,7 @@ class HTMLPurifier_AttrDef_HTML_Bool extends HTMLPurifier_AttrDef
public $minimized = true;
/**
* @param bool $name
* @param bool|string $name
*/
public function __construct($name = false)
{
@@ -97,7 +97,11 @@ class HTMLPurifier_AttrDef_URI_Host extends HTMLPurifier_AttrDef
// PHP 5.3 and later support this functionality natively
if (function_exists('idn_to_ascii')) {
$string = idn_to_ascii($string, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
if (defined('IDNA_NONTRANSITIONAL_TO_ASCII') && defined('INTL_IDNA_VARIANT_UTS46')) {
$string = idn_to_ascii($string, IDNA_NONTRANSITIONAL_TO_ASCII, INTL_IDNA_VARIANT_UTS46);
} else {
$string = idn_to_ascii($string);
}
// If we have Net_IDNA2 support, we can support IRIs by
// punycoding them. (This is the most portable thing to do,
@@ -220,15 +220,25 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
array(
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('auto'))
new HTMLPurifier_AttrDef_Enum(array('auto', 'initial', 'inherit'))
)
);
$trusted_min_wh = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit'))
)
);
$trusted_max_wh = new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_CSS_Length('0'),
new HTMLPurifier_AttrDef_CSS_Percentage(true),
new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit'))
)
);
$max = $config->get('CSS.MaxImgLength');
$this->info['min-width'] =
$this->info['max-width'] =
$this->info['min-height'] =
$this->info['max-height'] =
$this->info['width'] =
$this->info['height'] =
$max === null ?
@@ -245,6 +255,38 @@ class HTMLPurifier_CSSDefinition extends HTMLPurifier_Definition
// For everyone else:
$trusted_wh
);
$this->info['min-width'] =
$this->info['min-height'] =
$max === null ?
$trusted_min_wh :
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(array('initial', 'inherit'))
)
),
// For everyone else:
$trusted_min_wh
);
$this->info['max-width'] =
$this->info['max-height'] =
$max === null ?
$trusted_max_wh :
new HTMLPurifier_AttrDef_Switch(
'img',
// For img tags:
new HTMLPurifier_AttrDef_CSS_Composite(
array(
new HTMLPurifier_AttrDef_CSS_Length('0', $max),
new HTMLPurifier_AttrDef_Enum(array('none', 'initial', 'inherit'))
)
),
// For everyone else:
$trusted_max_wh
);
$this->info['text-decoration'] = new HTMLPurifier_AttrDef_CSS_TextDecoration();
@@ -45,7 +45,7 @@ class HTMLPurifier_ChildDef_Custom extends HTMLPurifier_ChildDef
protected function _compileRegex()
{
$raw = str_replace(' ', '', $this->dtd_regex);
if ($raw{0} != '(') {
if ($raw[0] != '(') {
$raw = "($raw)";
}
$el = '[#a-zA-Z0-9_.-]+';
+2 -2
View File
@@ -21,7 +21,7 @@ class HTMLPurifier_Config
* HTML Purifier's version
* @type string
*/
public $version = '4.10.0';
public $version = '4.12.0';
/**
* Whether or not to automatically finalize
@@ -890,7 +890,7 @@ class HTMLPurifier_Config
// zip(tail(trace), trace) -- but PHP is not Haskell har har
for ($i = 0, $c = count($trace); $i < $c - 1; $i++) {
// XXX this is not correct on some versions of HTML Purifier
if ($trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
if (isset($trace[$i + 1]['class']) && $trace[$i + 1]['class'] === 'HTMLPurifier_Config') {
continue;
}
$frame = $trace[$i];
@@ -100,7 +100,7 @@ class HTMLPurifier_ConfigSchema
* @param string $key Name of directive
* @param mixed $default Default value of directive
* @param string $type Allowed type of the directive. See
* HTMLPurifier_DirectiveDef::$type for allowed values
* HTMLPurifier_VarParser::$types for allowed values
* @param bool $allow_null Whether or not to allow null values
*/
public function add($key, $default, $type, $allow_null)
@@ -6,7 +6,7 @@ DEFAULT: false
<p>
When enabled, HTML Purifier will treat any elements that contain only
non-breaking spaces as well as regular whitespace as empty, and remove
them when %AutoForamt.RemoveEmpty is enabled.
them when %AutoFormat.RemoveEmpty is enabled.
</p>
<p>
See %AutoFormat.RemoveEmpty.RemoveNbsp.Exceptions for a list of elements
@@ -0,0 +1,12 @@
Core.AllowParseManyTags
TYPE: bool
DEFAULT: false
VERSION: 4.10.1
--DESCRIPTION--
<p>
This directive allows parsing of many nested tags.
If you set true, relaxes any hardcoded limit from the parser.
However, in that case it may cause a Dos attack.
Be careful when enabling it.
</p>
--# vim: et sw=4 sts=4
@@ -3,23 +3,154 @@ TYPE: hash
VERSION: 2.0.0
--DEFAULT--
array (
'maroon' => '#800000',
'red' => '#FF0000',
'orange' => '#FFA500',
'yellow' => '#FFFF00',
'olive' => '#808000',
'purple' => '#800080',
'fuchsia' => '#FF00FF',
'white' => '#FFFFFF',
'lime' => '#00FF00',
'green' => '#008000',
'navy' => '#000080',
'blue' => '#0000FF',
'aliceblue' => '#F0F8FF',
'antiquewhite' => '#FAEBD7',
'aqua' => '#00FFFF',
'teal' => '#008080',
'aquamarine' => '#7FFFD4',
'azure' => '#F0FFFF',
'beige' => '#F5F5DC',
'bisque' => '#FFE4C4',
'black' => '#000000',
'silver' => '#C0C0C0',
'blanchedalmond' => '#FFEBCD',
'blue' => '#0000FF',
'blueviolet' => '#8A2BE2',
'brown' => '#A52A2A',
'burlywood' => '#DEB887',
'cadetblue' => '#5F9EA0',
'chartreuse' => '#7FFF00',
'chocolate' => '#D2691E',
'coral' => '#FF7F50',
'cornflowerblue' => '#6495ED',
'cornsilk' => '#FFF8DC',
'crimson' => '#DC143C',
'cyan' => '#00FFFF',
'darkblue' => '#00008B',
'darkcyan' => '#008B8B',
'darkgoldenrod' => '#B8860B',
'darkgray' => '#A9A9A9',
'darkgrey' => '#A9A9A9',
'darkgreen' => '#006400',
'darkkhaki' => '#BDB76B',
'darkmagenta' => '#8B008B',
'darkolivegreen' => '#556B2F',
'darkorange' => '#FF8C00',
'darkorchid' => '#9932CC',
'darkred' => '#8B0000',
'darksalmon' => '#E9967A',
'darkseagreen' => '#8FBC8F',
'darkslateblue' => '#483D8B',
'darkslategray' => '#2F4F4F',
'darkslategrey' => '#2F4F4F',
'darkturquoise' => '#00CED1',
'darkviolet' => '#9400D3',
'deeppink' => '#FF1493',
'deepskyblue' => '#00BFFF',
'dimgray' => '#696969',
'dimgrey' => '#696969',
'dodgerblue' => '#1E90FF',
'firebrick' => '#B22222',
'floralwhite' => '#FFFAF0',
'forestgreen' => '#228B22',
'fuchsia' => '#FF00FF',
'gainsboro' => '#DCDCDC',
'ghostwhite' => '#F8F8FF',
'gold' => '#FFD700',
'goldenrod' => '#DAA520',
'gray' => '#808080',
'grey' => '#808080',
'green' => '#008000',
'greenyellow' => '#ADFF2F',
'honeydew' => '#F0FFF0',
'hotpink' => '#FF69B4',
'indianred' => '#CD5C5C',
'indigo' => '#4B0082',
'ivory' => '#FFFFF0',
'khaki' => '#F0E68C',
'lavender' => '#E6E6FA',
'lavenderblush' => '#FFF0F5',
'lawngreen' => '#7CFC00',
'lemonchiffon' => '#FFFACD',
'lightblue' => '#ADD8E6',
'lightcoral' => '#F08080',
'lightcyan' => '#E0FFFF',
'lightgoldenrodyellow' => '#FAFAD2',
'lightgray' => '#D3D3D3',
'lightgrey' => '#D3D3D3',
'lightgreen' => '#90EE90',
'lightpink' => '#FFB6C1',
'lightsalmon' => '#FFA07A',
'lightseagreen' => '#20B2AA',
'lightskyblue' => '#87CEFA',
'lightslategray' => '#778899',
'lightslategrey' => '#778899',
'lightsteelblue' => '#B0C4DE',
'lightyellow' => '#FFFFE0',
'lime' => '#00FF00',
'limegreen' => '#32CD32',
'linen' => '#FAF0E6',
'magenta' => '#FF00FF',
'maroon' => '#800000',
'mediumaquamarine' => '#66CDAA',
'mediumblue' => '#0000CD',
'mediumorchid' => '#BA55D3',
'mediumpurple' => '#9370DB',
'mediumseagreen' => '#3CB371',
'mediumslateblue' => '#7B68EE',
'mediumspringgreen' => '#00FA9A',
'mediumturquoise' => '#48D1CC',
'mediumvioletred' => '#C71585',
'midnightblue' => '#191970',
'mintcream' => '#F5FFFA',
'mistyrose' => '#FFE4E1',
'moccasin' => '#FFE4B5',
'navajowhite' => '#FFDEAD',
'navy' => '#000080',
'oldlace' => '#FDF5E6',
'olive' => '#808000',
'olivedrab' => '#6B8E23',
'orange' => '#FFA500',
'orangered' => '#FF4500',
'orchid' => '#DA70D6',
'palegoldenrod' => '#EEE8AA',
'palegreen' => '#98FB98',
'paleturquoise' => '#AFEEEE',
'palevioletred' => '#DB7093',
'papayawhip' => '#FFEFD5',
'peachpuff' => '#FFDAB9',
'peru' => '#CD853F',
'pink' => '#FFC0CB',
'plum' => '#DDA0DD',
'powderblue' => '#B0E0E6',
'purple' => '#800080',
'rebeccapurple' => '#663399',
'red' => '#FF0000',
'rosybrown' => '#BC8F8F',
'royalblue' => '#4169E1',
'saddlebrown' => '#8B4513',
'salmon' => '#FA8072',
'sandybrown' => '#F4A460',
'seagreen' => '#2E8B57',
'seashell' => '#FFF5EE',
'sienna' => '#A0522D',
'silver' => '#C0C0C0',
'skyblue' => '#87CEEB',
'slateblue' => '#6A5ACD',
'slategray' => '#708090',
'slategrey' => '#708090',
'snow' => '#FFFAFA',
'springgreen' => '#00FF7F',
'steelblue' => '#4682B4',
'tan' => '#D2B48C',
'teal' => '#008080',
'thistle' => '#D8BFD8',
'tomato' => '#FF6347',
'turquoise' => '#40E0D0',
'violet' => '#EE82EE',
'wheat' => '#F5DEB3',
'white' => '#FFFFFF',
'whitesmoke' => '#F5F5F5',
'yellow' => '#FFFF00',
'yellowgreen' => '#9ACD32'
)
--DESCRIPTION--
@@ -159,7 +159,7 @@ class HTMLPurifier_Encoder
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$in = ord($str{$i});
$in = ord($str[$i]);
$char .= $str[$i]; // append byte to char
if (0 == $mState) {
// When mState is zero we expect either a US-ASCII character
@@ -118,7 +118,7 @@ class HTMLPurifier_EntityParser
$entity = $matches[0];
$hex_part = @$matches[1];
$dec_part = @$matches[2];
$named_part = empty($matches[3]) ? @$matches[4] : $matches[3];
$named_part = empty($matches[3]) ? (empty($matches[4]) ? "" : $matches[4]) : $matches[3];
if ($hex_part !== NULL && $hex_part !== "") {
return HTMLPurifier_Encoder::unichr(hexdec($hex_part));
} elseif ($dec_part !== NULL && $dec_part !== "") {
@@ -132,9 +132,9 @@ class HTMLPurifier_HTMLModule
* @param string $element Name of element to add
* @param string|bool $type What content set should element be registered to?
* Set as false to skip this step.
* @param string $contents Allowed children in form of:
* @param string|HTMLPurifier_ChildDef $contents Allowed children in form of:
* "$content_model_type: $content_model"
* @param array $attr_includes What attribute collections to register to
* @param array|string $attr_includes What attribute collections to register to
* element?
* @param array $attr What unique attributes does the element define?
* @see HTMLPurifier_ElementDef:: for in-depth descriptions of these parameters.
@@ -23,13 +23,13 @@ class HTMLPurifier_HTMLModule_SafeScripting extends HTMLPurifier_HTMLModule
$script = $this->addElement(
'script',
'Inline',
'Empty',
'Optional:', // Not `Empty` to not allow to autoclose the <script /> tag @see https://www.w3.org/TR/html4/interact/scripts.html
null,
array(
// While technically not required by the spec, we're forcing
// it to this value.
'type' => 'Enum#text/javascript',
'src*' => new HTMLPurifier_AttrDef_Enum(array_keys($allowed))
'src*' => new HTMLPurifier_AttrDef_Enum(array_keys($allowed), /*case sensitive*/ true)
)
);
$script->attr_transform_pre[] =

Some files were not shown because too many files have changed in this diff Show More