Compare commits

...
984 Commits
Author SHA1 Message Date
sars f0d7b5e257 Merge branch 'devel' into userName 2024-05-27 02:47:54 +09:00
sars a0771d804f iOS에서 hover가 먹히게 div에 onClick추가 2024-05-26 00:45:19 -07:00
Hide_D c45758b054 game: 이벤트 클래식 유니크 최대 획득 확률 계수 수정 2024-05-22 17:45:45 +00:00
Hide_D a84f07f3ad game: 이벤트 클래식 시나리오 2024-05-22 17:43:29 +00:00
Hide_D 3c6ed3441b fix: MeekroDB 최신버전에서는 $db->get()으로 raw 호출을 먼저 시작해선 안됨 2024-05-22 17:00:27 +00:00
Hide_D 68cd61d86e fix: file_cache 문제 추가 수정 2024-05-22 16:47:20 +00:00
Hide_D 3470817e9e Nette FileStorage 요구 주소 문제 2024-05-22 16:45:29 +00:00
sars a3d7ef30dd 장수목록에서 장수명에 마우스를 올리면 본닉 공개 2024-05-20 19:03:51 -07:00
Hide_D db09e8da89 composer upgrade 2024-05-17 18:26:08 +00:00
Hide_D 37fa5321cc 초기 설치 코드 정돈, meekrodb 반영 2024-05-17 18:18:37 +00:00
Hide_D 63edb03193 APIHelper에 MeekroDBExceptionr에러시 logError 2024-05-17 18:16:54 +00:00
Hide_D 8d02102024 dep 2024-05-17 18:14:32 +00:00
Hide_D 75a13094e0 game: 해산시 군주외 장수는 즉시 임관 가능 2024-03-16 18:18:35 +00:00
Hide_D 7a4c70ada2 game: 강서유서 소설 월드 2024-03-16 18:07:59 +00:00
Hide_D 65c84a29e1 fix: 방랑군이동시 현재 소재 위치 확인 2024-03-16 18:07:42 +00:00
Hide_D eea34dadad fix: 이민족 수도 이동 2024-03-05 16:44:27 +00:00
Hide_D f1e6ac7b89 fix: 이민족 도시 이동 규칙 재작성
- 무한루프일 수 있으므로 그냥 SQL에 NOT IN을 넣자..
2024-02-29 10:35:32 +09:00
Hide_D 7b24f66f93 fix: 버그 수정 2024-02-29 10:28:10 +09:00
Hide_D b2b2934ce9 refac: 전체 penalty는 expire와 value
- 게임 개시시 expire가 되지 않은 것을 기준 value만 전달
- 즉, 페널티는 깃수 단위 적용
2024-02-29 10:27:04 +09:00
Hide_D 6ed3e673df game: 내정이라는 용어의 중의성 해소를 위해, 국가 성향의 내정이란 용어를 농상으로 바꾸고, 물자조달 커맨드를 내정의 하위 분류에서 국가로 이동 (#249)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/249
2024-02-29 10:18:00 +09:00
Hide_D aa7dcab1fd fix: 이민족 발동 시 수도가 이성이라 수도를 옮겼는데 다시 이성이 되는 경우 해결 (#250)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/250
2024-02-29 10:17:52 +09:00
devsamanddevsam e2e578e485 game: 내정이라는 용어의 중의성 해소를 위해, 국가 성향의 내정이란 용어를 농상으로 바꾸고, 물자조달 커맨드를 내정의 하위 분류에서 국가로 이동 2024-02-29 08:09:23 +09:00
devsamanddevsam 6cebc903c9 fix: typo 2024-02-29 08:02:11 +09:00
devsamanddevsam c0190959e3 fix: 이민족 발동 시 수도가 이성이라 수도를 옮겼는데 다시 이성이 되는 경우 해결 2024-02-29 08:01:02 +09:00
Hide_D bb26366769 fix: 이민족 발동 시 이성이 수도인 경우 문제 해결 2024-02-26 16:05:37 +00:00
Hide_D 71849a457b game: 종횡가의 전략 디메리트 감소
- 전략 쿨타임 2배 -> 4/3배
2024-02-26 16:01:16 +00:00
Hide_D 7c1a8d96a2 fix: 정규턴에 어긋나는 개인턴, 사령턴을 보정
- 조회시에만 사용
2024-02-26 15:58:41 +00:00
Hide_D cebd152daf fix: 경매장 소수점 제거 2024-02-26 15:43:07 +00:00
Hide_D 2ca03389d2 fix: 유니크 경매 항목 변경시 금액이 자동 조절되도록 수정
- 굳이 기존 값을 남길 이유가 없어보임
2024-02-24 15:14:24 +00:00
Hide_D cacf0981ce game: 턴 시간과 도시 지정을 같이 가능하도록 변경 2024-02-24 12:05:49 +00:00
Hide_D bcf5b5cb7d game: 턴 지정 단위를 1/30에서 1/60으로 변경 2024-02-24 11:46:32 +00:00
Hide_D 66b2f1a8f2 game: NPC는 건국 한턴 기다림 2024-02-24 11:45:08 +00:00
Hide_D 40ecca5440 game, feat: 커맨드마다 다른 랜덤값으로 유니크 시도
- 사전 거병 후 개인 턴일 때, 유니크 중복이 발생하는 경우가 있었음
2024-02-24 11:28:38 +00:00
Hide_D a96c2312d0 game, feat: 턴 시간 지정 방식을 30단계 중 선택하도록 변경
- 1분서버인 경우 120초 단위로
- 유산포인트 3000 -> 2500
2024-02-24 11:21:04 +00:00
Hide_D faff3f4e6a JSON -> Json
- 대체 왜 어떤 파일에는 에러가 나지 않았는가
2024-02-20 18:45:40 +09:00
Hide_D 83abf44380 feat: 유저의 제재 목록을 장수 생성/빙의시 가져옴 2024-02-18 03:24:21 +00:00
Hide_D e83960d67f fix: 사전거병시 삭턴 정상 반영 2024-02-18 03:10:42 +00:00
Hide_D c6b2e64c05 penalty에 sendPrivateMsgDelay추가 2024-02-18 03:08:21 +00:00
Hide_D 029f719112 fix: 스탯 계산 시에 캐시 사용하는 부분 수정 시도 (#241)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/241
2024-02-17 00:01:49 +09:00
Hide_D 46f460c8ad Merge branch 'devel' into stat_cache_fix 2024-02-17 00:01:40 +09:00
Hide_D af4401d9bb fix: 사전거병 후 군주가 사라지는 경우에 대한 수정 (#247)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/247
2024-02-17 00:01:34 +09:00
devsamanddevsam 2f00aee947 아주 약간 효율적으로 수정 2024-01-26 22:17:06 +09:00
devsamanddevsam dd2b032fa3 리뷰 내용 반영 2024-01-26 22:13:44 +09:00
Hide_D 1b858ae36c fix: onCalcOpposeStat이 제대로 전파되지 않았음 2023-12-30 04:15:33 +00:00
devsamanddevsam 69f4d8e2c7 fix: 사전거병 후 군주가 사라지는 경우에 대한 수정 2023-12-29 12:07:59 +09:00
Hide_D f24aea0120 fix: 수정된 턴 시간 변경 로직에서 바뀌기 이전 턴을 시드로 계속 사용하는 문제 수정 (#246)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/246
Reviewed-by: Hide_D <hided62@gmail.com>
2023-12-27 17:42:48 +09:00
Jinhyun Kim f6dc7f49e2 fix: 수정된 턴 시간 변경 로직에서 바뀌기 이전 턴을 시드로 계속 사용하는 문제 수정 2023-12-27 17:25:51 +09:00
Hide_D c1f105226f refac: 기존 commandButton.php 삭제
- 이젠 MainControlBar로 대체됨
2023-12-25 08:28:36 +00:00
Hide_D cecab2b0cf feat: 이호경식 발동시 '어느 국가'인지 바로 표기 2023-12-25 08:07:57 +00:00
Hide_D 39f4e89b03 feat: HasRouteWithEnemy에서 "교전 중인 국가가 아닙니다" 추가
- 경로에 도달할 방법이 없는 것은 맞으나..
- 교전중이 아니라는 것에 의미가 있음
2023-12-25 08:05:34 +00:00
Hide_D 83f595a27a feat: 종전시 세력 정보란에 문구 남김 2023-12-25 07:59:57 +00:00
Hide_D b0db11544d fix: 인사부 연동 스크립트 오타 수정 2023-12-25 07:56:27 +00:00
Hide_D 8e3551cb11 feat: 턴 시간 변경을 직관적인 동작으로 재 설계
- '다다음턴' 부터 시간을 00:00 ~ 59:59까지 랜덤하게
2023-12-25 07:51:54 +00:00
Hide_D 61d99a3043 초기 3년 이전에도 하야 가능
- 기존엔 1인국의 문제가 있었으나, 이미 NPC국이 자리를 채웠다.
2023-12-25 07:30:25 +00:00
Hide_D fe80deff0c 【가상모드27-e】 아시아 명장전(비급+파죽지세) (#244)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/244
2023-11-21 00:12:38 +09:00
포스트모더니즘 536c00f5a8 【가상모드27-e】 아시아 명장전(비급+파죽지세) 2023-11-21 00:04:20 +09:00
포스트모더니즘 66ed8635dd 【가상모드14-b】 걸그룹대전(비급) 시나리오 추가 2023-11-20 23:49:45 +09:00
포스트모더니즘 311c485cec fix: 불가침 제의를 같은 국가로 지정할 수 있는 버그 수정 2023-10-30 12:23:16 +09:00
포스트모더니즘andHide_D 5b5cf4e6d3 misc: 허보 대상 도시 선택 시에 선포 중인 경우 추가 2023-10-30 09:21:47 +09:00
포스트모더니즘 c5ed2d47fc fix: 스탯 계산 시에 캐시 사용하는 부분 수정 시도 2023-10-29 09:05:29 +09:00
포스트모더니즘 428ec0d0ed misc: 유니크 경매 취소 시에 경매 경매가 취소되었다고 표시되는 문제 수정 2023-10-29 08:37:36 +09:00
Jinhyun Kim 96c5f987d6 misc: 등용장 수락 시에도 국가 이름 볼드 처리 2023-10-14 07:57:27 +09:00
Hide_D f0ae28b087 fix: 이전 커밋에서 ' 하나를 "로 변경 2023-09-15 12:54:31 +09:00
Jinhyun Kim fa4a266d77 misc: 개인 기록에 전략 수행 내역이 남도록 수정, 백성동원 대상 도시도 남도록 수정 2023-09-09 07:48:48 +09:00
Hide_D 32e854858e feat: 랜덤 턴 초기화 시간 범위를 상세하게 알려줌 2023-09-03 17:11:41 +00:00
Hide_D f13371e679 fix: 저격에서 raiseType을 저격시도/저격발동 일치 2023-08-17 10:25:04 +09:00
Hide_D 2420f594a6 game: 자동 출병 조건 일부 수정
- 국고 병령이 2000 밑이더라도, 유저장은 출병
2023-08-14 07:30:16 +00:00
Hide_D b7b0a1050c feat: 도시 함락 시 수비 장수에게 트리거 발동 2023-08-14 06:04:43 +00:00
Hide_D d2a90157b9 fix: 트래픽에서 접속자수가 제대로 집계되지 않는 문제 2023-08-13 07:26:09 +00:00
Hide_D a32cb3a2c0 fix: 수비X 관련 warning
- 버그는 있으나 의도대로는 작동하였음
2023-08-12 10:07:58 +00:00
Hide_D 7c0a3a6955 fix: 접속량 정보가 기록되지 않았음 2023-08-12 10:06:08 +00:00
Hide_D 7d2e2945a1 fix: 연감 한번 더 수정 2023-08-10 19:08:21 +09:00
Hide_D dc526c7359 fix: 연감 수정 2023-08-10 19:06:40 +09:00
Hide_D 6c4cb484da fix: 연감 1개월차 수정 2023-08-10 19:06:01 +09:00
Hide_D d41246de9d fix: 초기 시작시 연감이 안보임 2023-08-10 19:04:55 +09:00
Hide_D 6d40783224 fix: 수극으로 인한 저격 소모 2023-08-07 13:19:52 +00:00
Hide_D 6eb6014e80 game: 출병시 전멸시페이즈 증가 적용
- 마지막 페이즈가 아닐 때 전멸 시 페이즈 증가
2023-08-07 11:26:43 +00:00
Hide_D 103cf3f882 game: 파죽지세 시나리오에서 수비끔시 훈사영향없음 2023-08-07 11:24:17 +00:00
Hide_D 5969e0c82b fix: 수극이 다른 저격과 따로 동작 2023-08-05 10:12:34 +00:00
Hide_D 945f9027dd game: StrongAttacker의 보정을 공방40%씩으로
- 병종저격하면 동률
2023-08-05 09:10:17 +00:00
Hide_D 0bf3145042 game: 파죽지세 모드, 접경귀환 2023-08-05 09:01:54 +00:00
Hide_D 905669755f feat: 접경 귀환 기능 추가 2023-08-05 08:57:15 +00:00
Hide_D 57b12e8c04 fix: Session에서 로그인 정보를 세심히. 2023-08-05 08:47:45 +00:00
Hide_D eccd883edc feat: NotOccupiedCity constraint 2023-08-05 07:59:26 +00:00
Hide_D 895b134cd0 feat: InstantAction 개념 추가 2023-08-05 07:54:55 +00:00
Hide_D 7258573e4d misc: 닥공전 이름을 파죽지세로 변경 2023-08-05 07:20:12 +00:00
Hide_D cbdfa6f6fc feat: 닥공전 기능 추가
- 장수 상대로 공격자인 경우
  - 공, 방 50%씩
2023-08-05 07:15:36 +00:00
Hide_D ed25c58410 fix: 오타 수정 2023-08-05 07:14:40 +00:00
Hide_D 16cfa46864 feat: scenarioEffect 추가
- 모든 General에 iAction으로 작동
2023-08-05 06:53:19 +00:00
Hide_D e54a0a6668 feat: 시나리오 생성 시 에러가 발생하면 메시지를 띄움 2023-08-05 06:52:50 +00:00
Hide_D eb545724ea fix: 천통후 이벤트에서 유산 포인트를 얻을 수 있는 문제 수정 2023-08-05 05:19:40 +00:00
Hide_D 7858b48bad fix: b_betting 수정 2023-08-03 16:20:32 +00:00
Hide_D a4ed41edbe fix: mergeQueryColumn위치 수정 2023-08-03 14:19:23 +00:00
Hide_D b5a9e52c43 fix: 인사부는 GeneralLite가 아니라 General 필요
- 추방시 명성 깎이는 문제 때문
2023-08-03 13:35:55 +00:00
Hide_D c6166d3295 fix: 수뇌임명 안되는 버그 수정
- 아니 대체 왜 경고를 안 띄우는거야!
2023-08-03 13:32:37 +00:00
Hide_D 9520d29109 fix: General 생성 코드 수정 2023-08-03 13:31:30 +00:00
Hide_D 3edfff146e General 클래스를 General, GeneralLite로 분리 (#236)
내부 코드 사용례에서 General 테이블의 column을 일부만 가져오는 경우가 다수 있습니다.

다만 General 클래스에서 각종 iAction에 해당하는 트리거 함수 호출을 위해서는 모든 column을 다 가져와야 정상 동작이 가능한 만큼, iAction interface를 구현한 General 클래스와, 구현하지 않은 GeneralLite 클래스 둘로 나눕니다.

또한 General 클래스에서는 필요한 column을 다 가져오도록 변경합니다.

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/236
2023-08-03 21:32:01 +09:00
Hide_D 38416ccdf8 fix,refac: 잠재적인 버그 위치 수정
- aux가 null이 아니라 0으로 되고 있었음
- (0 == null) == true이니 그동안 되고는 있었겠으나..
- increaseInheritancePointRaw()를 호출하도록 변경
2023-08-01 16:24:55 +00:00
Hide_D eeb5eabd12 feat: increaseInheritancePoint에 더해진 후의 값 반환 2023-08-01 16:24:52 +00:00
Hide_D 41273f97db feat,refac: increaseInheritancePointRaw 추가
- ownerID만으로 처리 가능
2023-08-01 16:24:43 +00:00
Jinhyun KimandGitea 0e23677e1b Merge pull request 'fix: 징병 가능 여부 판별 시 상대 년도 판별 로직 오류 해결' (#233) from jyp9/core:relyearfix into devel 2023-07-29 14:57:59 +00:00
Hide_D 0f085c7f36 fix: zero-ref 2023-07-27 17:27:11 +00:00
Hide_D bd90076441 phan: update config.php 2023-07-27 17:27:08 +00:00
Hide_D 1801bdf55b fix: 설문조사 시 아이템 추첨 문제
-  tryUniqueItemLottery()는 itemObjs 배열을 요구
- itemObjs 배열은 GeneralQueryMode::Full 에서만 사용가능
- 즉, Lite여서는 안됨!
2023-07-21 13:26:26 +00:00
Hide_D f27f0edfb6 fix: 빙의시 경고 제거 2023-07-21 13:22:04 +00:00
Hide_D 02f23e7db4 fix: 토너먼트 경고 해제 2023-07-21 13:09:45 +00:00
Hide_D 9871e24811 fix: defaultEventColumn에 turntime 추가
- 많이 쓰일 것으로 예상
2023-07-18 11:05:07 +09:00
Hide_D a7dac2ce15 fix: mergeQueryColumn에서 query 계산 방식 변경
- 요청 쿼리 = queryMode + reqColumn로 변경
- 기존에는 null일 경우에만 queryMode 전체, null이 아니면 queryMode를 한 단계 낮추고,
   reqColumn을 더하는 형태였음
- 지난 버그에서 혼동을 일으키는 요소였으므로 수정
2023-07-18 10:54:36 +09:00
Hide_D ed1d2cbf0d Revert "fix: 발령에서 destGeneral에 turntime 필요"
This reverts commit 06ca32802b.
2023-07-18 10:49:37 +09:00
Hide_D 06ca32802b fix: 발령에서 destGeneral에 turntime 필요 2023-07-17 17:44:45 +00:00
Hide_D 568b45f93a fix: minimumColumn에 owner 필요 2023-07-17 17:43:32 +00:00
Hide_D 1ca07286a4 Revert "game: 국가 임관 시, 기존 등용장 무효화"
This reverts commit 376aed9787.
2023-07-12 20:19:59 +10:00
Hide_D 376aed9787 game: 국가 임관 시, 기존 등용장 무효화 2023-07-11 22:47:24 +10:00
Hide_D 246751b4dd feat: 등용장 일괄 무효화 추가 2023-07-11 22:43:09 +10:00
Hide_D 7f3a9d69ca misc: FIXME 2023-07-11 22:11:01 +10:00
Hide_D a4106f6242 game: 등용장 수락은 재야 상태에서만 가능 2023-07-11 22:02:07 +10:00
Hide_DandGitea f233e8241e Merge pull request 'feat,refac: General 테이블의 벌점(갱신) 항목을 별도 테이블로 분리' (#232) from general_access_log into devel 2023-07-08 09:10:53 +00:00
Hide_D 79dedea47c fix: 물자원조 조사 2023-07-08 02:04:17 +00:00
Hide_D e106a6a3cf fix: queryMode 조회 문제
- 아니 PHP야 enum에 ->value 좀..
2023-07-07 18:44:36 +00:00
Hide_D ee3d84d7b0 refac: General 객체 생성을 GeneralQueryMode를 활용
- 기존 $constructMode
- 버그 있음..?
2023-07-07 18:39:23 +00:00
Hide_D b4f197b7d8 feat: GeneralQueryMode Enum 추가
- mergeQueryColumn, createGeneralObjListFromDB, createGeneralObjFromDB 호출시
 column 특수 모드 지정
2023-07-07 18:14:55 +00:00
Hide_D e3c89a37aa fix: 구 내정보 페이지 변수 조회 문제 2023-07-07 17:29:03 +00:00
Hide_D ad0770d1be fix: 접속량 정보 변수명 2023-07-07 17:20:24 +00:00
Hide_D 161ed97a34 fix: GeneralAccessLogColumn 인자 값 문제
- PHP 제발 반성 좀... 왜 ->value가 필요해..?
2023-07-07 17:12:15 +00:00
Hide_D f66008da56 refac, fix: General 객체 생성 과정에서 accessLog 분리
- 생성자 인수 1개 추가,
- mergeQueryColumn에서 $accessLogColumn에 정상적으로 enum[] 반영
- createGeneralObjListFromDB를 쿼리 1회 분리
- General에 getAccessLogVar() 추가
  - 변경 기능 제공 예정 '없음'
- 변경된 생성자에 맞게 호출 부 변경
- NPC인 경우 accessLog 조회값이 null일 수 있으므로 반영
2023-07-07 17:08:05 +00:00
Hide_D 6b400f76cf fix: 오타 수정 2023-07-07 15:58:18 +00:00
Hide_D 758ae06fd9 refac, wip: con 삭제,생성 관련 2023-07-07 10:57:52 +00:00
Hide_D 49429e1e7e refac, wip: con -> refreshScore 2023-07-07 10:57:52 +00:00
Hide_D c9dd873019 refac, wip: 벌점(connect, con) 변경
- 벌점: refreshScoreTotal
- 순간벌점: refreshScore
2023-07-07 10:57:52 +00:00
Hide_D 3ae49456b1 fix: general_access_log에 벌점 관련 데이터 누락 2023-07-07 10:57:52 +00:00
Hide_D 9bf7bd0fda refac,wip: refresh 수치를 이전 중
- connect, con을 잊었음!
2023-07-07 10:57:51 +00:00
Hide_D a9b51977d4 refac: lastrefresh를 general_access_log로 이전
- last_refresh에 index를 걸 것인지는 고려 필요
  - 안 거는게 차라리 나을 수도 있음
- 불필요해보이는 값 확인: nation_id,
2023-07-07 10:57:51 +00:00
Hide_D 50408ed516 feat: TableName Enum 2023-07-07 10:57:51 +00:00
Hide_D b0cdf3ccb5 refac: General::lastconnect 삭제
- 안쓰는데..?
- api_log로 어느새 이전된건가?
2023-07-07 10:57:51 +00:00
Hide_D ea80b85b33 refac: 갱신 시 refresh를 general_access_log로 이동 2023-07-07 10:57:51 +00:00
Hide_D 39ca3e2bb9 feat: GeneralAccessLog 구조 변경
- 기본값 최대한 많이 사용
2023-07-07 10:57:51 +00:00
Hide_D f8cc0c9c92 feat: GeneralAccessLog table 준비
- general 테이블에서 유저 접속과 관련한 로그만 분리
- ip 정보는 api 접속부에서 기록하므로 제외
2023-07-07 10:57:51 +00:00
Hide_D 7a9ef6454c fix: 정체불명의 ts type error fix
- 이 변경이 없어도 잘 되어야함. type에 undefined로 놓는게 어딨어?
2023-07-07 10:57:50 +00:00
Hide_D d48c27dccb misc: 관리자5번 도구에서 벌점 정보 제거 2023-07-07 10:57:50 +00:00
Hide_D 5a565c2678 feat: formatListOfBackticks에서 인자로 BackedEnum 사용 가능 2023-07-07 10:57:50 +00:00
Hide_D 1e0875ae73 game: 국력 계산식에 '벌점' 제거 2023-07-07 10:57:50 +00:00
Hide_D 33759d24e5 refac: 접속 로그를 날짜_refresh.txt에서 api_log로 통일
- path가 refresh로 고정
2023-07-07 10:57:50 +00:00
Hide_D 033e75de5c refac: 구 멀티 검사 페이지 삭제
- IP로만 구분하던 방식
- IP를 general에서 없애므로 삭제
2023-07-07 10:57:45 +00:00
Hide_D f2f8374fd4 fix: 쉼표를 주의하시오 2023-07-04 10:24:32 +09:00
Hide_D e891525d56 refac: general_turn, nation_turn 불필요한 인덱스 제거 2023-07-03 17:04:38 +00:00
Hide_D 93bc8304ce misc: 몇 가지 눈에 보이는 오타 수정 (#231)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/231
2023-07-03 22:32:42 +09:00
Jinhyun Kim d4218f409c 몇 가지 눈에 보이는 오타 수정 2023-07-03 20:59:05 +09:00
Hide_D 462de95866 misc: php xdebug profiler ignore 2023-07-02 17:42:56 +00:00
Hide_D dad477ed14 misc: 불필요산 #app css 제거
- 필요하다면 vue page에서 직접 요구하여야 함.
2023-07-02 17:06:01 +00:00
Hide_D 660258f715 refac: 메인 페이지 바 표시 형식 변경
- 상 하단 분리 대신 하단의 position:fixed bar로 변경
- iPhone에서 좌우 스크롤이 유도되는 것은 완전 해결되지 않음
- 모든 컨텐츠가 viewport 밖을 넘어서지 않도록 않도록 해야 할 것으로
- 예: 500px viewport, 498px content
2023-07-02 17:05:14 +00:00
Hide_D 9f6c7d9489 fix: 누락된 php breakpoint 수정 2023-06-30 16:34:14 +00:00
Hide_D de17d87f47 fix: 비일관적인 breakpoint 정정
- md가 아니라 lg를 기준으로 잡아야 함
- lg의 기준 breakpoint를 940으로 변경
- is100pxMode의 기준 역시 lg breakpoint와 일치
2023-06-30 16:30:44 +00:00
Hide_D f8ebcf91b1 fix: 삼성 브라우저 draggable workaround 2023-06-28 14:50:52 +00:00
Hide_D d25d414057 dep: vuedraggable-es 2023-06-28 14:50:37 +00:00
Hide_D 96a9254bf8 misc: tabSize 4 2023-06-28 13:45:24 +00:00
Hide_D 96643567d4 game: 애니집결 시나리오의 대사 빈도를 낮춤 2023-06-24 16:53:21 +00:00
Hide_D 0a6db3d21f fix: 이민족 발동시 서버 시간 변경 문제 2023-06-23 11:27:59 +00:00
Hide_D 8a4cbbb976 game: 애니집결 10차 시나리오 2023-06-23 19:28:28 +09:00
Hide_D 696ba0b341 fix(game): 병가의 세율에 따른 인구 증감이 '정수'로 고정되는 문제
- onCalcNationalIncome에서 pop은 0~0.125 사이임
2023-06-18 13:23:01 +09:00
Hide_D 4efcbaed6a misc: d_setting에 관련 코드가 추가되어 TODO 제거 2023-06-11 21:57:45 +09:00
Hide_D eda5ecb124 feat: d_setting에 ServerEnv 추가 2023-06-11 21:56:26 +09:00
Hide_D 0ef69178a5 feat: 이민족 발동 시 장수수에 따라 턴시간 조절 2023-06-11 21:44:22 +09:00
Hide_D 5596eca326 feat: 서버 제어용 변수 공간 추가 2023-06-11 21:40:07 +09:00
Hide_D af2dec7e2c refac: 턴시간 변경에 락 무시하는 기능 추가 2023-06-11 21:27:14 +09:00
Hide_D 435dae801f refac: _admin1 턴시간 변경을 changeServerTerm으로 이전 2023-06-11 21:25:53 +09:00
Hide_D 320c8191dc feat: ServerTool::changeServerTerm
- 서버 턴 시간을 바꾸는 명령
- 기존 _admin1.php
2023-06-11 21:24:53 +09:00
Hide_D 803e18e3c3 fix: 이민족 이벤트 종료시 메시지 2023-06-11 21:02:57 +09:00
Hide_D fbac218c34 fix: 이민족 발동 시, 초기 이성이 없으면 동작하지 않도록 2023-06-10 22:41:19 +09:00
Hide_D 2e6ea3a00d fix: isunited warning 수정 2023-06-08 23:31:46 +09:00
Hide_D 1f8812c939 fix: MAX_RNG_SUPPORT_BIT warning 2023-06-08 23:23:05 +09:00
Hide_D 44c2323883 fix: 임시 땜빵 베팅 2023-06-07 00:23:36 +09:00
Hide_D 82fb532e4b fix: 조사 (으)로 미 반영부분 수정 2023-06-06 16:51:42 +09:00
Hide_D ae6ca5c1ec fix: 성벽 선제 시 분쟁 대상이 도시로 나타나지 않는 버그 수정 2023-06-06 16:41:13 +09:00
Hide_D 30ac7da4d7 misc: 이민족 생성 시, 전쟁 금지 및 임관 금지 해제 2023-06-04 20:22:45 +09:00
Hide_D 8c30634fd1 fix: 리셋 시 최근 읽은 메시지 번호를 초기화해야 함 2023-06-03 10:58:15 +09:00
Hide_D 59761743dc misc: 이민족 소환 권한을 2명에게 부여 2023-05-22 21:56:15 +09:00
Hide_D 5952dba533 fix: 천통시 이민족 소환에 npc 여부를 제대로 계산하지 않는 문제 2023-05-22 21:52:35 +09:00
Hide_D 2518ac021d fix: ProvideNPCTroopLeader 경고 우회 2023-05-22 02:48:41 +09:00
Hide_D e656c1e567 fix: 천통시 이민족 권한을 유저에게 부여
- 군주가 NPC인 경우 참모
- 참모도 NPC라면 각 수뇌까지
2023-05-22 02:43:54 +09:00
Hide_D b89c045f85 feat: 천하통일 시 군주에세 이민족이 침입 이벤트 권한 부여
- 세가지 종류 난이도
  - 천통국가 기준 [장수 수, 종합 스탯, 기술 수치, 숙련 수치]
  - 어려움:  2배, 1.2배, 최고등급, 1배
  - 보통: 2배, 1.2배, 동일 기술, 0.5배
  - 쉬움: 1배, 1배, 20% 낮은 기술, 숙련 없음
- 이민족 멸망시 타 이민족으로 임관
2023-05-22 02:41:17 +09:00
Hide_D d347054ad0 feat: 이민족 침입 메시지 타입 추가 2023-05-22 02:38:35 +09:00
Hide_D 3ebc44ea5a fix: RaiseInvader의 중첩 호줄 대비
- isunited 변수를 빠르게 1로 설정
- 만약 RaiseInavder를 빠르게 두번 호출하더라도 isunited 변수를 검사하게 하여 대응 가능
2023-05-22 02:19:47 +09:00
Hide_D 57c8c3f6a4 feat: MessageType 간이 생성 함수 추가
- General 객체에서 생성
- 왜 여태까지 이 함수가 없었을까?
2023-05-22 02:15:45 +09:00
Hide_D fee769714d feat: System MessageTarget를 빠르게 생성하는 함수 2023-05-22 01:55:09 +09:00
Hide_D 9fcb24533a feat: sendPrivateMsgAsNotice 인자로 MessageTarget 추가 2023-05-22 01:44:25 +09:00
Hide_D 1061632290 feat: 단순한 공지용 개인 메시지 전송 기능 2023-05-22 01:41:35 +09:00
Hide_D 7dc297a266 fix: 성벽 선제 후 전투 종료시 점유율 관련 문제 2023-05-20 13:04:37 +09:00
Hide_D f019a642a2 fix: 구형 관리자 도구 warning 수정 2023-05-20 12:56:57 +09:00
Hide_D 5554ac3003 fix: 성벽 전투 반영 2023-05-20 03:37:09 +09:00
Hide_D 7f9ad8b7d5 fix: 정란/벽력의 성벽선제가 정상적으로 반영되지 않는 문제
- 수비/성벽
- 점유율
2023-05-20 01:03:19 +09:00
Hide_D 82af3a2e2d fix: 수비자에 수비 도시 정보가 입력되지 않는 버그 수정 2023-05-19 19:16:39 +09:00
Hide_D 7a4fcb30dc fix: 거울세계에서 국가 규모 승급이 일어나지 않던 버그 수정 2023-05-12 01:21:12 +09:00
Hide_D 256326f5d4 game: 정란, 벽력거 설명 추가 2023-05-12 00:07:01 +09:00
Hide_D 505f615203 game: 성벽선제인 경우에만 성벽도 선제공격 2023-05-12 00:07:01 +09:00
Hide_D 4e504e9679 game: 성벽이 선제공격 2023-05-12 00:07:01 +09:00
Hide_D 18f9d87a29 fix: 성벽 선제가 호출조차 되지 않는 버그 수정 2023-05-12 00:07:01 +09:00
Hide_D 2ad0c6e509 fix: 도시 관련 전투 제어 2023-05-12 00:07:00 +09:00
Hide_D 74b9e0b4a5 feat: CrewType에 iAction 개념을 넣고 처리할 수 있도록
- GameUnitDetail에 iAction 리스트 추가

fix: 누락분 수정

fix: crewtype 미지정시 기본 병종
2023-05-12 00:05:25 +09:00
Hide_D 486ac65767 wip: process_war에서 defenderList 변경
- defenderList를 General[] 에서 WarUnit[]으로 변경
- extractBattleOrder를 WarUnit을 받도록 변경
2023-05-10 02:31:43 +09:00
Hide_D 483641bcd5 feat: extractBattleOrder 함수가 공격자를 받아서 처리할 수 있도록 변경 2023-05-10 01:28:00 +09:00
Hide_D ffdacc2cfb game: 차병종 상성 변경
- 정란: 현행 유지
- 충차: 현행 유지
- 벽력거: 받는 피해 44% 증가
  - 정란의 상성과 동일하게 변경
- 목우: 주는 피해 20% 감소
2023-05-10 00:59:56 +09:00
Hide_D 4eac86da58 game: 저지시 쌀을 소모하도록 변경
- 오르는 숙련 대비 0.25배
- 즉, 일반 공격력 대비 0.9 * 0.25만큼
2023-05-10 00:39:10 +09:00
Hide_D 77fc38c899 misc: 세력장수에서 숫자 셀에는 숫자 대소비교 필터 설정 2023-04-30 19:37:52 +09:00
Hide_D 0bf49ebfb9 game: 능력치가 상한에 도달하면 더이상 오르지 않음 2023-04-30 00:29:15 +09:00
Hide_D 93f0516121 Revert "game: 스탯 제한을 순수 스탯 대상으로만 변경"
This reverts commit 71a3ffa21c.
2023-04-30 00:22:14 +09:00
Hide_D 36406c8001 game: 물자조달도 전방 내정 감소가 적용 2023-04-30 00:15:41 +09:00
Hide_D 836adcfe3c game: 전방 내정시, 수도가 전방이어도 감쇠되도록 설정
- 185년까지는 해당 없음(디버프 * 0%)
- 이후 1년마다 실제 적용량 대비 5%씩 가산 적용됨
- 205년이 되면 수도여도 전방 내정 감쇠가 그대로 적용됨
2023-04-30 00:15:17 +09:00
Hide_D 71a3ffa21c game: 스탯 제한을 순수 스탯 대상으로만 변경 2023-04-29 23:47:47 +09:00
Hide_D 38f10b5f09 game: 최대 레벨, 능력치 제한을 255로 변경 2023-04-29 23:46:22 +09:00
Hide_D da6b1fe7f1 game: 내부 스탯 제한을 2중으로 2023-04-29 23:40:30 +09:00
Hide_D 034e6374cc game: 최대 환산 능력치를 300으로 제한 2023-04-29 23:30:11 +09:00
Hide_D 9b95163f24 fix: 명성 최대 레벨 지정이 없었음 2023-04-29 23:18:55 +09:00
Hide_D 91b7934ee3 fix: KakaoUtil의 저장 키 문제 2023-04-25 23:09:01 +09:00
Hide_D 41216893a1 fix: 감찰부 대상 API 순서에 따라 잘못 표기 되는 문제
- API 결과값과 현재 대상 비교하는 코드 추가
2023-04-23 16:53:17 +09:00
Hide_D 3553b87748 fix: 지도 제목에 툴팁 표기 고장 수정
- 동작하지 않는 vMyTooltip 제거
2023-03-30 02:39:57 +09:00
Hide_D 3e5e584fce fix: 오타 수정
- 영향받는 코드는 없었을 것으로.
2023-03-30 01:19:52 +09:00
Hide_D afb53d121b fix: 특기 초기화시 가득차면 사용 풀이 리셋되지 않는 버그 수정 2023-03-28 10:05:48 +09:00
Hide_D 1780122936 fix: 모든 내특/전특 사용시 에러나는 문제 수정 2023-03-28 09:54:24 +09:00
sars 64aa5d041f Revert "긴급 버그 패치, 내특 줄 수 있는게 하나도 없으면 강제로 상재로 주고 턴 넘기는것으로 긴급패치, 히데님이 알아서 제대로 고칠것, (2로 해두면 상재가 아니라 아에 버그가 떠서 그냥 롤백시키고 히데님이 다 고치는걸로 방치하기로 결정)"
This reverts commit fbccfbb65e.
2023-03-27 09:54:37 -07:00
sars fbccfbb65e 긴급 버그 패치, 내특 줄 수 있는게 하나도 없으면 강제로 상재로 주고 턴 넘기는것으로 긴급패치, 히데님이 알아서 제대로 고칠것 2023-03-27 09:49:00 -07:00
Hide_D 13eb0d4eae fix: 토너먼트 표기 문구 수정 2023-03-26 15:56:04 +09:00
Hide_D 3969c47f07 Revert "fix: 임시로 대문에서 로그인 체크를 직접 하도록 변경"
This reverts commit c7e0d6d2cb.
2023-03-26 15:55:38 +09:00
Hide_D c7e0d6d2cb fix: 임시로 대문에서 로그인 체크를 직접 하도록 변경 2023-03-26 15:52:06 +09:00
Hide_D 9e997a7ee2 feat: 도시 장수 정의에 nationID를 추가 2023-03-26 00:58:53 +09:00
Hide_D 9a8f70d87b fix: 감찰부 안보이는 버그 수정
- query로 옮겨서 생기는 문제
2023-03-26 00:58:32 +09:00
Hide_D 7132aeab0c fix: installVue3Components() 호출부 통일 2023-03-26 00:48:05 +09:00
Hide_D 994c73adb2 feat: 설문조사 정보도 DB정보를 이용하여 한번만 처리 2023-03-25 03:07:38 +09:00
Hide_D 9206b74500 feat: 이미 읽은 메시지를 DB에서 처리 2023-03-25 02:09:23 +09:00
Hide_D 5294aefbbd misc: 동향 변경 안내 시간 단축 2023-03-24 03:03:50 +09:00
Hide_D 8f0f586af9 fix: 버그 수정 2023-03-24 02:44:14 +09:00
Hide_D 9121533b93 fix: 국가 승급을 Event로 떼내어야 함
- 부대장 지급보다 앞으로
2023-03-24 02:43:07 +09:00
Hide_D 90bff7b210 misc: 연도 업데이트 2023-03-22 23:22:46 +09:00
Hide_D 55f7b87ced misc: GetConst의 cache key를 getVersion으로 2023-03-22 23:19:28 +09:00
Hide_D bee4de377a feat: 버전 정보 페이지 추가 2023-03-22 23:09:53 +09:00
Hide_D b02911038b fix: 갱신시마다 커맨드 테이블을 다시 불러줘야 함 2023-03-22 22:58:05 +09:00
Hide_D 9b4d5455e5 feat: GetConst에서 버전 정보 반환 2023-03-22 22:54:47 +09:00
Hide_D ca3e64f3b9 feat: MenuItem에 funcCall 타입 추가후 처리 2023-03-22 22:44:42 +09:00
Hide_D 4d2b5ced82 feat: 메뉴 구성에 line 추가 2023-03-22 22:04:35 +09:00
Hide_D e385820301 fix: classMap에서 orig.php만 있고, 본 php는 없는 케이스 고려 2023-03-22 21:50:55 +09:00
Hide_D ec7c97d696 feat: hightlight btn, 토너먼트/베팅장 강조 2023-03-22 02:23:14 +09:00
Hide_D aae730d39c fix: gatewayButton 2023-03-21 01:51:39 +09:00
Hide_D 3c412f2803 fix: cr 시나리오 병종을 현재 버전에 맞게 수정 2023-03-21 01:44:27 +09:00
Hide_D 25769a9435 fix: sqlite3 db ignore 대상 추가 2023-03-21 01:42:25 +09:00
Hide_D 6c76d688b5 fix: 메시지 삭제 안되는 버그
- GetRecentMessage에서 keepRecent 관련 오동작 수정
  - 왜 이걸 넣었는지 생각해보기로..
2023-03-21 01:38:58 +09:00
Hide_D 790c58f2b6 feat: 메시지 빠른 답장 대상 지정 2023-03-20 02:12:57 +09:00
Hide_D 1eba863cc4 misc: 폰트 설정이 다르더라도 툴바 버튼 줄 수 유지 2023-03-20 01:13:21 +09:00
Hide_D fbe5739d82 feat: 메시지 응답시, 읽음 처리 2023-03-20 01:06:53 +09:00
Hide_D f8f8ef7dd3 misc: MainControlBar에 붙은 class 정리 2023-03-20 01:02:41 +09:00
Hide_D ecc375ef41 fix: customize scss에 맞게 다시 수정 2023-03-20 00:16:32 +09:00
Hide_D 9e17e58ecb dep: package update
- decl type 변경 포함
2023-03-20 00:02:04 +09:00
Hide_D 18f7e7b7c1 dep: package update 2023-03-19 23:12:09 +09:00
Hide_D b15b09cc1e dep: package update 2023-03-19 22:59:00 +09:00
Hide_D 49f2f85f79 dep: package-update 2023-03-19 17:45:17 +09:00
Hide_D 2245383d9e dep: remove bootstrap-vue-3 2023-03-19 17:17:45 +09:00
Hide_D e619a6b509 misc: 내무부에서 에디터 폼 최소 높이 높임 2023-03-19 16:59:13 +09:00
Hide_D fb9e750fe2 game: 외교권자가 아니면 외교 메시지 알림 없음 2023-03-19 16:51:06 +09:00
Hide_D 457aa0e4a5 misc: getNewMsgToast 힌트에 따라 수정 2023-03-19 15:38:49 +09:00
Hide_D 761b91b7db fix, refac: bvn에 맞게 tooltip directive 변경
- installVue3Component로 통합
- boostrap-vue-next 0.7.3 directive 문제 우회
2023-03-19 14:41:09 +09:00
Hide_D 31f4472a8a dep: upgrade bv3 bvn 2023-03-19 13:29:58 +09:00
Hide_D a79585f8de fix: 메시지 보러가기를 누르더라도 이미 읽음 처리를 해야함 2023-03-19 12:56:55 +09:00
Hide_D 69fbbbb51a feat: 개인/외교 메시지 수신시 버튼 추가 2023-03-19 12:54:53 +09:00
Hide_D 5eecbfc6f8 misc: package.json 요구로 임시 처리 2023-03-19 12:54:29 +09:00
Hide_D 9121780d82 feat: is1000pxMode에 widthMode 통합 2023-03-18 09:03:37 +09:00
Hide_D 6691aa3526 feat: PageFront에 토너먼트 베팅장 활성시 색 변경 2023-03-18 02:10:13 +09:00
Hide_D 582163ab46 fix: 부대장의 특기를 없앰.
- 특기 수령 년도를 999년으로 변경
2023-03-17 13:28:23 +09:00
Hide_D 394a70319f game: cr 시나리오에서 '척사'를 3등급 병종 문제로 제거 2023-03-17 02:18:23 +09:00
Hide_D 4d340abdcf feat: BaseAPI의 launch()에 타입 지정
- APIRecoveryType이 명시
2023-03-17 01:39:10 +09:00
Hide_D 6b9cfe46a0 feat: APIHelper에서 recovery 반환 타입 경로 추가 2023-03-17 01:18:20 +09:00
Hide_D 1d4707fb20 fix: recovery를 typescript API와 매칭 2023-03-17 01:16:55 +09:00
Hide_D d673024a10 feat: APIRecoveryType을 포함한 리턴 방법 2023-03-17 01:10:59 +09:00
Hide_D 3513aae088 fix: 지도 도시 민감도 문제 수정
- touchend는 touchmove와는 별개이므로 함께 처리
2023-03-17 00:30:22 +09:00
Hide_D 83c43d0261 fix: ProvideNPCTroopLeader 2023-03-16 23:59:24 +09:00
Hide_D 53cd8aeb5d fix: cr 시나리오에 선포가 없는 버그 수정 2023-03-16 19:27:28 +09:00
Hide_D 65b861d7ee fix: cr맵 배경 500px 2023-03-16 12:22:23 +09:00
Hide_D a5432e59d0 fix: CreateManyNPC 경고 제거 2023-03-16 03:49:19 +09:00
Hide_D e67b45e9cd game: 거울세계 구조 수정 2023-03-16 03:20:14 +09:00
Hide_D 8a8d9db7f9 game: 910 이벤트 시나리오 추가 수정
- 기본 이벤트 로직 오버라이드
  - 깃 끊김 없음
- 특수 커맨드(제한없는 건국, 인구이동, 맹훈련)
- 특수맵에 규모 적용
2023-03-16 01:24:06 +09:00
Hide_D 602cf3bf13 game: cr_건국,맹훈련,인구이동 추가
- 특수 맵 커맨드에 맞춤
- 건국: 소,중성 제한 없음
- 맹훈련: 훈련/사기진작의 2/3를 동시에
- 인구이동: 도시의 인구를 다른 곳으로 이동
2023-03-16 01:12:46 +09:00
Hide_D ab2e43e8dd fix: 국가가 하나도 없을 땐 CreateManyNPC가 동작하지 않아야 함 2023-03-16 00:07:04 +09:00
Hide_D 49b39c34eb fix: ProvideNPCTroopLeader는 국가가 없을땐 동작하지 않아야함 2023-03-16 00:04:33 +09:00
Hide_D fb5946fba5 feat: 소재 도시가 공백지여야하는 조건 작성 2023-03-15 23:19:01 +09:00
Hide_D 3ff4d51778 fix: 명령 선택시 지도의 배경이 안보이는 버그 수정 2023-03-15 04:11:50 +09:00
Hide_D 49d1bf4bad game: CR 맵 초기화 2023-03-15 03:48:37 +09:00
Hide_D 6a67a7de98 misc: 도시 렌더러에서 배경 클래스 지정 2023-03-15 02:11:47 +09:00
Hide_D f132d285e9 game: 랜덤임관 모드에서 초기 장수 제한 해제
- 사전 거병이 가능하므로, 시간에 따른 제한은 필요없을 것으로 판단
2023-03-15 01:15:10 +09:00
Hide_D f97b6e10d3 fix: 삼성 브라우저 다크모드 색상 틀어짐 수정 시도 2023-03-13 03:03:05 +09:00
Hide_D 90509516dd fix: Json::decode에서 빈줄은 array조차 아님 2023-03-13 02:44:58 +09:00
Hide_D 0a35505fa4 fix: 트래픽 일람에서 새 줄 파싱 문제 2023-03-13 02:43:44 +09:00
Hide_D 80a674436a fix: PageFront에서 부대 탑승여부가 보이지 않는 버그 2023-03-13 02:32:14 +09:00
Hide_D 50bf2a4614 fix: 도시 상인 % 표기 문제 수정 2023-03-13 00:00:01 +09:00
Hide_D 2f69be49e1 fix: 도시 정보에서 민심을 소수점 한자리로 제한 2023-03-12 18:48:50 +09:00
Hide_D 40fb8a4836 dep: lodash를 lodash-es 로 변경 2023-03-12 17:47:03 +09:00
Hide_D 0da9ffee9b fix: 일부 메인페이지 색상값을 옮겨오지 않은 버그 수정 2023-03-12 17:38:16 +09:00
Hide_D c88e3d1bfe fix: 메인, 사령부의 alert를 toast로 이동 2023-03-12 17:32:00 +09:00
Hide_D ae76ce0abd fix: PageFront 능력치 상승 기준이 엉뚱하게 잡혀있던 버그 수정 2023-03-12 17:17:53 +09:00
Hide_D d17b2518df 전역 하드코드 이벤트를 동적 변경 영역으로 이동 (#230)
기존에 작성해두었던 EventHandler 시스템으로 하드코드 이벤트 이동
- 매달
  - 보급선 설정
  - 전쟁 단기 수입 설정
  - 부대장 부여
- 1월
  - 유산 포인트 계산
  - 도시 인구 변화
  - 수입
  - 관직 제한 해제
  - 재난
  - 상인
  - 새해 알림
  - 특기 부여
- 4월
  - 관직 제한 해제
  - 재난
- 7월
  - 유산 포인트 계산
  - 도시 인구 변화
  - 수입
  - 관직 제한 해제
  - 재난
  - 상인
- 10월
  - 관직 제한 해제
  - 재난
- 천통 시
  - 유산 포인트 계산

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/230
2023-03-12 17:14:49 +09:00
Hide_D 4901a2d384 fix: 거병 시 인구 정보를 0이 아니라 null로 보내는 문제 수정 2023-03-12 16:38:32 +09:00
Hide_D 47bf5cdd17 misc: PageFront 로딩 직후에는 갱신 완료 메시지 없음 2023-03-09 20:32:10 +09:00
Hide_D 076c0cd604 fix: 메인 페이지 로그인, _119 페이지 링크 복구 2023-03-09 20:15:40 +09:00
Hide_D c4ccc451ec fix: 첫 건국 시 국가방침이 null임 2023-03-09 03:03:18 +09:00
Hide_D 3d9bb9c2e0 fix: index.php인경우 Session에 gameLogin 필요 2023-03-09 02:49:28 +09:00
Hide_D 4472cd0bdc fix: 가오픈 기간에 PageFront에 안오는 정보 수정 2023-03-09 02:48:21 +09:00
Hide_D efc36e223c misc: v_front -> index 2023-03-09 02:40:15 +09:00
Hide_D af2b82616f misc: index->old_index.php 2023-03-09 02:39:56 +09:00
Hide_D 6f5d7ff84b feat: Vue3로 새롭게 작성한 메인 페이지 (#229)
- v_front.php
- API 추가
  - General/GetFrontInfo
  - Global/GetGlobalMenu
- DTO 추가
  - MenuItem, MenuMulti, MenuSplit
- 글로벌 메뉴 출력 방식 변경
  - d_setting/GlobalMenu.php

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/229
2023-03-09 02:25:31 +09:00
Hide_D 4ba9468fae fix: 임시 토스트 본문 색상 변경 2023-03-09 02:18:04 +09:00
Hide_D 7905ddb7bf feat: scrollToSelector 2023-03-09 02:17:55 +09:00
Hide_D fdef4caa65 feat: 외부 호출이 불가능한 API 타입 정의 2023-03-09 02:17:41 +09:00
Hide_D ebaf63d541 feat: 10단위 column 분리 2023-03-09 02:17:00 +09:00
Hide_D 0e92973a05 fix: 누락된 메시지 def 수정 2023-03-09 02:16:05 +09:00
Hide_D 6a4fa8ee0d feat: Message 정의를 좀더 상세히 2023-03-09 02:15:42 +09:00
Hide_D 0081c86d1e fix: 국방 줄바꿈 수정 2023-03-05 00:09:59 +09:00
Hide_D 051fdee9b9 fix: MeekroDB에서 바뀐 설정 반영
- 설정하는 옵션이 기본값으로 변경
2023-03-04 14:16:14 +09:00
Hide_D 20330e19df fix: 불가침파기제의 warning 2023-03-01 12:43:30 +09:00
Hide_D bb5c9d8fd6 fix: CityConstBase warning 2023-03-01 12:38:45 +09:00
Hide_D 18ae530edf dep: php package update 2023-03-01 12:38:42 +09:00
Hide_D 294897df54 fix: Test 코드 변경 2023-03-01 12:38:33 +09:00
Hide_D 4fcafe88a7 fix: Session은 singleton이므로 생성자가 public이면 안됨 2023-03-01 04:33:13 +09:00
Hide_D 968e4afc8f fix: DummySession이 login 상태로 취급되지 않음 2023-03-01 04:29:37 +09:00
Hide_D 4193b884b0 fix: APIHelper DummySession 초기화 문제 2023-03-01 04:08:52 +09:00
Hide_D 9371de1b4a feat: PartialReservedCommand에 reloadCommandList 노출 2023-03-01 02:31:13 +09:00
Hide_D c5c7f96c1a feat, refac: 메인 페이지에서 커맨드 리스트를 동적으로 받아옴 2023-03-01 02:17:09 +09:00
Hide_D e721642a10 fix: timeout, retry 지정 2023-02-28 00:44:59 +09:00
Hide_D 4f0b18cc3c fix: DummySession, Session singleton 문제
- DummySession 호출 후 Session 호출시에도 DummySession이 나와야 함
- 함수 상속 관계 재 설정
2023-02-28 00:43:56 +09:00
Hide_D 904e26f56e fix: 토너먼트 자동개최모드 설정 관련 2023-02-24 20:02:58 +09:00
Hide_D 7a3642296a feat: 전투 시뮬레이터에 히든 버프 반영 가능 2023-02-24 00:25:29 +09:00
Hide_D 87e57aea0e feat: 전투 시뮬레이터에 시드 값 입력 가능
- 시드 값 입력시 반복 횟수는 1회로 고정
- 스킬 성공 여부는 동일하나, 실제 수치가 조금 다른 경우가 관측 이유는 추후 확인
- 히든 버프는 아직 미 반영
2023-02-23 23:48:09 +09:00
Hide_D ea256790ec game: 계략에서 도시 인구별 방어 계산식을 제곱근에서 로그로 변경
- (log(장수수 + 1, 2) - 1.25) * 0.04
- 8명까지는 기존 계산식과 큰 차이 없음
2023-02-23 22:59:10 +09:00
Hide_D 4cbd824ee0 fix: 초기 갱신 없이 국가 삭제시 버그 수정 2023-02-23 00:30:42 +09:00
Hide_D 4db1a4b32e fix: 접속자, 접속량 계산에 문제가 있던 부분 수정 2023-02-23 00:25:44 +09:00
Hide_D c060e05553 refac: 메시지 전달 j_ 코드를 API로 변경
- 메시지 전송
- 최근 메시지 수신
- 이전 메시지 수신
- 메시지 응답
- 연락처 수신
- 메시지 삭제
2023-02-22 01:29:00 +09:00
Hide_D 92cd195276 fix: 사령부 타 수뇌 텍스트 복사의 턴 순서도 수정 2023-02-21 02:32:18 +09:00
Hide_D f9b270fef3 fix: 텍스트 복사에서 턴 번호가 제대로 옮겨지지 않는 버그 수정 2023-02-21 02:29:23 +09:00
Hide_D 3f12dfd8ba feat: 턴 조작기에 '텍스트 복사' 추가 2023-02-21 02:26:52 +09:00
Hide_D d7e57f30eb fix: 사령부 복사하기 순서 지연 수정 시도 2023-02-21 02:04:03 +09:00
Hide_D ff822561cd game: 기병의 수비시 전투력 향상
- 기존 대비 전투력 5% 향상
2023-02-21 01:59:59 +09:00
Hide_D 273973f4b6 fix: Uri 기본 사용 방법 변경 2023-02-20 02:23:54 +09:00
Hide_D c648e2df85 fix: WebUtil Namespace 2023-02-20 01:27:52 +09:00
Hide_D 9b7e0ef169 fix, dep: 사용불가능한 phpuri를 league/uri로 대체
- 테스트 아직 없음
2023-02-20 01:02:18 +09:00
Hide_D 6eccd248ea dep: composer 2.5.4 2023-02-20 00:28:04 +09:00
Hide_D eaaa1c5da8 game: 초토화가 치안, 수비, 성벽도 낮추도록 변경 2023-02-05 15:59:33 +09:00
Hide_D 95776cda5c fix: 궁병이 아닌 경우에도 '맞 선제'가 정상 작동하도록 수정
- 궁병선제사격을 선제사격시도, 선제사격발동으로 분리
- 맞선제의 기준을 궁병이 아니라 '선제'의 활성화 여부로 구분
2023-01-28 03:09:44 +09:00
Hide_D 8ae0323dcc fix: 선제 사격에 저격을 쓰지 못하게 해야함 2023-01-28 02:56:35 +09:00
Hide_D f2d0020d92 fix: 피장파장은 피장파장을 대상으로 할 수 없음 2023-01-27 00:51:12 +09:00
Hide_D 67f3004eb0 fix: 이미 다른 부위에 입찰중인 경우 경매가 열리다 마는 버그 수정 2023-01-27 00:43:11 +09:00
Hide_D f933c0616b fix: 턴시간 고정이 0분만 가능한 버그 수정 2023-01-26 14:36:59 +09:00
Hide_D a240c6f901 game: 아시아 명장전(빙의전용) 생성 2023-01-02 20:05:07 +09:00
Hide_D e2c2ae0360 feat, refact: 메시지 응답 2022-12-05 01:55:38 +09:00
Hide_D bcd0117cdd misc: 메시지 삭제 API 정리 2022-12-05 01:42:54 +09:00
Hide_D 83f233cc99 feat, refac: 메시지 삭제 2022-12-05 01:40:12 +09:00
Hide_D 4f21eab7b1 feat, refact: 메시지 연락 리스트 수신 2022-12-05 01:10:41 +09:00
Hide_D 864ddf7efe feat, refac: 메시지 전송 2022-12-05 00:46:16 +09:00
Hide_D 9d3636cc49 misc: APIHelper에서 array가 반환된 경우 result: true 자동 삽입 2022-12-05 00:42:09 +09:00
Hide_D ce4f656030 fix: 정상 깃수 기준을 1 이상으로 변경 2022-12-02 00:43:43 +09:00
Hide_D a94f080cde fix: 미접속 유산 포인트 부여에서 '이벤트 깃수'를 카운트하는 버그 수정 2022-12-02 00:41:44 +09:00
Hide_D 71ca873c7a fix: msgOption은 null을 허용해야함. 2022-12-02 00:23:07 +09:00
Hide_D 6e0d13e1fb fix: 장수 생성시 보너스 스탯 표기 오류 2022-12-01 22:24:09 +09:00
Hide_D 059c4d999a game: 맞 선제시 이전 패치에서 변경된 전투력 반영 2022-12-01 01:13:43 +09:00
Hide_D f52e357e8a fix: 디버그용 코드 수정 2022-12-01 01:02:13 +09:00
Hide_D 761496be5c game: 정란, 벽력에 선제사격 추가, 벽력 공격력 약화
- 6페이즈 전투 기준으론 공격력 유지
- 벽력기준 돌격, 수비전 등에서 상대적 약화
2022-12-01 01:00:30 +09:00
Hide_D 551972d876 feat, refac: 오래된 메시지 불러오기 2022-11-30 01:32:17 +09:00
Hide_D 81c2fc4d43 game: 궁병의 선제 사격을 일반 공격력의 50%에서 2/3로 변경 2022-11-30 00:14:24 +09:00
Hide_D 3e542fcbfa game: 궁기병의 보병 상성 상향 수준 억제
- 공격력: 12.5% 향상
- 방어력: 9.1% 향상
2022-11-30 00:10:44 +09:00
Hide_D c9ab2c593d game: 궁기병의 보병 상대 전투력 향상
- 공격력 25% 향상 (20% 열세)
- 방어력 20% 향상 (25% 열세)
2022-11-30 00:07:46 +09:00
Hide_D 0c9e00e90a game: 목우의 수비 상성 약화
- 1.2(초기) -> 0.8(무상성) -> 1(현재)
- 25% 아군 피해 증가
2022-11-30 00:04:24 +09:00
Hide_D ea17972478 fix: 제거한 troop.ts 파일 빌드 수정 2022-11-29 02:13:43 +09:00
Hide_D 3d40df9755 feat, refac: 최근 메시지 API 2022-11-29 02:06:57 +09:00
Hide_D b4ac348645 Refac: 메시지 타입 지정으로 MessageType Enum 사용 2022-11-29 01:53:55 +09:00
Hide_D 374611f66c refac: MessageType enum 2022-11-29 01:49:19 +09:00
Hide_D 39b66fd626 misc: 사용되지 않는 구버전 부대편성 코드 제거 2022-11-28 23:51:21 +09:00
Hide_D 75dca322b4 fix: UserID가 null인 경우 대응 2022-11-10 17:14:21 +09:00
Hide_D cfdae1ddfa misc: 관리를 위해 mkdir에 group permission 부여 2022-11-05 15:17:57 +09:00
Hide_D 054a6c7073 feat: 모든 API를 기록하는 시스템
- sqlite3에 기록
- 느려지지 않기를...
2022-11-05 15:00:13 +09:00
Hide_D e93d9e6cf5 feat: API에서 민감한 argument 지정 2022-11-05 14:59:52 +09:00
Hide_D 30d99c6fc3 fix: DummySession에서 get이 잘못됨. 2022-11-05 14:58:22 +09:00
Hide_D 56c9b44c93 game: 이벤트 유니크 분실 메시지를 흥미롭게 변경 2022-11-02 21:17:04 +09:00
Hide_D 919ae5a863 game: 무작위 세계 이벤트 시나리오 가오픈 재생성 주기 단축 2022-11-01 23:00:59 +09:00
Hide_D 43b8e546f6 feat: 시나리오 별 사전 생성 시 재 생성 주기 결정 가능 2022-11-01 23:00:25 +09:00
Hide_D b90aef662b game: 무작위 세계 시나리오 초기 등록 2022-10-30 22:13:39 +09:00
Hide_D 1da47863ae feat: 전역 아이템 망실 이벤트 추가 2022-10-30 22:13:25 +09:00
Hide_D 81bd5c1914 feat: 무작위건국, 무작위수도이전 커맨드 추가 2022-10-30 21:47:24 +09:00
Hide_D b14f9a638f fix: 무작위장수명 모드에서 장수명이 제대로 지정되지 않음 2022-10-30 21:41:12 +09:00
Hide_D 8ff3a5a7a8 feat: GameConst에서 유니크 획득 확률 조정 가능 2022-10-30 21:29:48 +09:00
Hide_D 48c77bd6a2 feat: 장수명 무작위 생성 모드 가능 2022-10-30 15:16:40 +09:00
35a017c1dc fix: 천통 후 서버시드 출력 시 괄호를 열지 않고 닫았던 문제 수정 (#227)
Co-authored-by: Jinhyun Kim <lewha0@gmail.com>
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/227
Reviewed-by: Hide_D <hided62@gmail.com>
Co-authored-by: lewha0 <lewha0@noreply.storage.hided.net>
Co-committed-by: lewha0 <lewha0@noreply.storage.hided.net>
2022-10-10 03:29:48 +09:00
Hide_D a3e8a10da9 game: 건국 시점 유산 포인트 베팅 제공량 상향 2022-10-10 01:39:42 +09:00
Hide_D 142b96836e refac: 신규/복귀 유저 유산 포인트 지급 로직을 조금더 최적화 2022-10-05 00:26:04 +09:00
Hide_D 9be0d2ec2d refac: storeOldGeneral을 General::kill로 이동 2022-10-04 20:38:18 +09:00
Hide_D fd817650e7 fix: 지급 버그 수정 2022-10-04 11:32:52 +09:00
Hide_D 3c6cb96a9b feat: 신규/복귀 유저에게 장수 생성 시 유산 포인트 제공
- 이벤트 깃수 제외 500포인트
- 8기까지 적립
2022-10-04 11:25:40 +09:00
Hide_D c4537454f9 fix: 최대 임관년도 수 계산 버그 재 수정 2022-10-04 10:02:39 +09:00
Hide_D 82cdaa433e fix: 최대 임관년도 수 계산 버그 2022-10-04 01:07:11 +09:00
Hide_D 32dd3ff43f misc: AI에서 삭턴NPC 구분 기준을 1턴 추가 2022-10-04 00:13:52 +09:00
Hide_D 6a5840faaa fix: AI 후방 발령 누락분 수정 2022-10-03 23:38:53 +09:00
Hide_D 5b0a3b064d fix: AI 후방 발령 로직 버그 수정
- 징병시 인구 소모가 없는 경우 후방 발령 제외
- NPC 수뇌일때와 유저 수뇌일 때 도시 인구 계산식 다른 버그 수정
2022-10-03 23:37:07 +09:00
Hide_D 14b8bb9790 fix: 2번 연속 멸망 시 유산 포인트 계산 오류 2022-10-03 11:32:22 +09:00
Hide_D 650f4a5903 fix: 구조상 베팅 당첨 포인트는 은퇴시 반영되어야 함 2022-10-03 00:37:18 +09:00
Hide_D c50410a6da game: 은퇴시 토너먼트 보정치를 100%로
- 실수였음!
2022-10-02 23:27:41 +09:00
Hide_D b2a676cd8b game: 옥란백용구 향상 최대 30% -> 50% 2022-10-02 23:25:00 +09:00
Hide_D 50a75e4543 refac, game: 은퇴 시 포인트 반영 방식 변경
- 반영하지 않고 은퇴 이후로 넘기는 포인트 추가
- 은퇴시 계수를 Obj로 이동
2022-10-02 19:41:38 +09:00
Hide_D 22172ac66f fix: null coalesing 수정 2022-10-02 19:39:35 +09:00
Hide_D 392aaa343d fix: calcGenType을 updateInstance()로 이동 2022-10-02 19:36:17 +09:00
Hide_D d924f47d58 fix: warning 발생 제거 2022-10-02 19:35:05 +09:00
Hide_D 3b70cbe724 fix: GeneralAI env 설정 관련 버그 수정 2022-10-02 17:46:20 +09:00
Hide_D 5c3233f883 misc: 서버 리셋 페이지에서 기본 설정값 변경
- 자율 행동 전부 선택
- 자율 행동 기본 시간 24시간
- 사실모드: 가상
2022-10-02 17:43:40 +09:00
Hide_D b570bfa9d4 fix: NPC선전포고, 긴급포상에서 내부 NPC 국가 상태를 업데이트하도록 수정 2022-10-02 17:37:40 +09:00
Hide_D 270cb25285 refac: GeneralAI에서 상태를 추가 업데이트할 수 있도록 구조 변경 2022-10-02 17:33:23 +09:00
Hide_D 7d3b0db924 game: 계략 성공률을 5%p 하향
- 계략 성공률에 인구수를 반영하기 이전과 비교하여 1명있을 때에는 동일
- 한명도 없을때는 5%p 상승
- 두명 이상일 때에는 이전 대비 성공률 하향
2022-10-02 15:59:30 +09:00
Hide_D 74d310e113 fix: 불가침에서 '까지'는 해당 월을 포함하여야 함 2022-10-02 15:55:31 +09:00
Hide_D 45afb1c090 fix: 수동 은퇴 시 명예의전당에 등록되지 않는 버그 2022-09-27 10:00:44 +09:00
Hide_D 40fc2f8bbf fix: NPC 순간이동이 보급이 끊긴 도시에도 갈 수 있는 버그 수정 2022-09-24 22:29:58 +09:00
Hide_D a9de5a92e1 build: pre-commit에 lint 제거 2022-09-24 20:58:56 +09:00
Hide_D c592b00c3f game: 피장파장에 추가되었던 글로벌 전략 1턴 제거 2022-09-24 20:57:44 +09:00
Hide_D 2c81be4d12 game: 계략 방어 확률에 도시 거주 장수 수 반영
- sqrt(장수 수) * 5%p
2022-09-23 21:59:51 +09:00
Hide_D f10289f7b6 game: 피장파장은 이제 전략
- 글로벌 쿨 1턴
- 피장파장 쿨 8턴
2022-09-23 21:56:15 +09:00
Hide_D c1f06b4ce5 fix: 최대 임관 년도 수 제어 규약 우회 2022-09-22 11:54:47 +09:00
Hide_D 9ad3dbba90 game: 배신 관련 최종 수정, 20%부터, +10%p씩
- 공지 추가
2022-09-21 23:25:20 +09:00
Hide_D 12c62f87f7 game: 초기 배신 수치 추가 보정
- 배신 수치를 '2'로 변경.
- 명성 패널티를 30%로 시작해서 45%, 60%
2022-09-21 23:16:29 +09:00
Hide_D 635f1ae077 feat, game: 초반 '배신 수치' 1 증가, 배신 패널티 증가
- 184년 1월부터 배신수치 1 증가.
- 배신 패널티 당 15%, 최대 6회
2022-09-21 23:12:56 +09:00
Hide_D c89bd2f63f fix: 하야, 망명 시 최대 임관 년수가 반영되지 않는 버그 수정 2022-09-21 22:48:55 +09:00
Hide_D 2f94a8a2ca fix: 가오픈 기간 중 사망 메시지에서 조사가 중복되어 나오던 문제 수정 (#226)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/226
Reviewed-by: Hide_D <hided62@gmail.com>
2022-09-14 12:07:08 +09:00
Jinhyun Kim 85b0d35af0 fix: 가오픈 기간 중 사망 메시지에서 조사가 중복되어 나오던 문제 수정 2022-09-14 11:42:19 +09:00
Hide_D b25acacb1e fix: 징병 특기에 '비용 감소' 제거 누락 2022-09-10 19:04:46 +09:00
Hide_D c05a43f3b1 fix(oauth): 이메일 변경 시 oauthID를 받아오지 못하는 분기 수정 2022-09-09 03:28:18 +09:00
Hide_D d99976daa9 fix(oauth): 카카오로그인에서 이메일만 바뀐 경우 이메일 갱신 2022-09-09 03:11:34 +09:00
Hide_D 62f53d09bf feat, game: 징병 전특 리밸런싱, 징병/소집해제시 인구 변동 트리거 설정 2022-09-06 19:48:52 +09:00
Hide_D 88c78ec892 game, misc: 작위 상승 메시지 변경 2022-09-01 02:49:20 +09:00
Hide_D 006ca76922 refac: ExecuteEngine 반환 타입 변경 2022-08-30 22:51:14 +09:00
Hide_D 8cb2e2a447 fix: OAuth Redirect UTI가 사전 값과 다른 경우 domain 보정 2022-08-28 18:00:53 +09:00
Hide_D 517c85d003 misc: oauth.php 에러 상세 표기 2022-08-28 17:37:55 +09:00
Hide_D 83556b710c fix, feat: HTTP_HOST가 다른 경우에도 oauth redirect 허용
- oauth 대상에서 redirect 허용 host를 설정해야함.
2022-08-28 17:24:25 +09:00
Hide_D a43b9091f8 feat: WebUtil::replaceDomain 2022-08-28 17:21:37 +09:00
Hide_D e83a1bef49 fix, misc: 사이시옷 수정 2022-08-28 15:45:44 +09:00
Hide_D 1147a8262c fix: 아이템 이름 오기 2022-08-28 15:41:50 +09:00
Hide_D 8a987cc55e fix: 조사 관련 문제 수정 2022-08-28 15:40:52 +09:00
Hide_D b28ca864f9 dep: package update 2022-08-28 15:30:35 +09:00
Hide_D 4bf77a5c55 game: 궁병 공격 시도, 추가페이즈 선제 공격
- 수비 선제와 구조적으로 동일
- 첫번째 상대에게 선제 사격
- 궁병과 궁병의 대결인 경우 항상 맞 선제 사격
2022-08-28 14:35:14 +09:00
Hide_D 4ebc20f182 game: 전투 첫 페이즈 계략시도 보정은 무장 제외 2022-08-28 14:17:09 +09:00
Hide_D 9eff1ccaed fix: 경매장 이름 풀 난수 생성기에 seed 초기화값 문제 수정 2022-08-27 12:15:12 +09:00
Hide_D 66170c98dd game: 수비 끔 시 사기 감소량 -3 => -6 2022-08-27 03:00:16 +09:00
Hide_D 397c054c66 game: 유니크 경매 제한 시간 감소
- 1분턴 마감시간 기준 1시간 -> 30분
2022-08-27 02:57:01 +09:00
Hide_D 0611551dc0 game: 의병모집 생성량 변경
- 3 + 연감 기준 평균 장수수 / 8 (반올림)
- 국가별 장수수가 평균 80명부터 역전
2022-08-27 02:46:44 +09:00
Hide_D 008f88d995 game: 전투시 얻는 기술량에서 공격자 상향
- 공격자 기술: 공격자가 입은 피해 * 0.012 (구 0.01)
- 수비자 기술: 수비자가 입은 피해 * 0.009 (구 0.01)
2022-08-27 02:39:47 +09:00
Hide_D 7fe450bc07 Revert "revert: LazyVarUpdater에 \BackedEnum 롤백"
This reverts commit a88ec71b44.
2022-08-26 22:16:06 +09:00
Hide_D a88ec71b44 revert: LazyVarUpdater에 \BackedEnum 롤백 2022-08-26 17:30:24 +09:00
Hide_D 8a5a3b67f7 refac: utilGame/getNPCColor 2022-08-26 01:06:43 +09:00
Hide_D 63771da876 misc: utilGame/index.ts 2022-08-26 00:34:56 +09:00
Hide_D 68891fafdb misc: CityColumn enum 2022-08-26 00:34:45 +09:00
Hide_D df31300a0b refac: GeneralBasicCard의 부대장 요구 정보를 간소화 2022-08-26 00:34:42 +09:00
Hide_D 16fb782bbf refac: LazyVarUpdater의 key로 BackedEnum 허용 2022-08-26 00:34:39 +09:00
Hide_D ed3e013a53 misc: GeneralColumn enum 추가 2022-08-26 00:34:32 +09:00
Hide_D 0bf568a655 feat: 국방 설정 시, 작성자와 작성 일시를 기록 2022-08-26 00:34:15 +09:00
Hide_D a5e481af96 fix: utilGame format에서 한단계 다르게 차이나는 버그 수정 2022-08-21 18:53:55 +09:00
Hide_D 78a9641c14 dep: lodash -> lodash-es 2022-08-21 18:14:36 +09:00
Hide_D b517000650 game: 성벽 공격 시 소모 쌀 20% 감소 2022-08-21 17:52:25 +09:00
Hide_D 1d20eb3c3e game: 초반 M장 생성 시 무지장 대량 생성 2022-08-21 17:42:33 +09:00
Hide_D 8248ccbcd5 game: 시간이 지남에 따라 성벽 강화
- 183년 기준 동일.
- 220년 기준 40% 전투력 상승
2022-08-20 15:03:58 +09:00
Hide_D b880b9bace game: NPC가 조금 더 상위병종을 시도할 확률을 높임 2022-08-20 14:39:51 +09:00
Hide_D 2da374410b game: 필살 계수 향상 방식 너프 2022-08-20 14:29:54 +09:00
Hide_D fff8f9493b game: 유니크 아이템 경매 시 현재가보다 1% 더 높아야 함 2022-08-20 14:15:49 +09:00
Hide_D 987baaa307 misc: 아시아 명장전 장수 구성 수정 2022-08-19 21:11:02 +09:00
Hide_D 9512ea9b52 feat: APICoveryType에 맞게 InvalidResponse 확장 2022-08-18 01:08:38 +09:00
Hide_D b0f3c1c97d feat: APIRecoveryType Enum 생성 2022-08-18 01:08:35 +09:00
Hide_D e823b97cf2 fix: 세션 관리 api 에러 2022-08-18 01:08:28 +09:00
Hide_D 203859ee5f dep: denque 추가 2022-08-16 23:58:21 +09:00
Hide_D 4870e2fa30 feat: GetRecentRecord 추가
- 메인페이지 최신 로그
2022-08-16 23:57:47 +09:00
Hide_D 970b702a2b fix: 빙의장은 제대로 유산을 받지 못하는 버그 수정 2022-08-13 03:18:31 +09:00
Hide_D 053288b227 fix: applyDB시 rankVarRead 처리 오류 (=은퇴 버그 수정)
- 은퇴는 applyDB 이후에 실행됨
- applyDB 코드 오류로 이후 key값 문제로 은퇴가 실행되지 않음
2022-08-13 03:12:09 +09:00
Hide_D e9b975bea7 fix: 의병모집에서 명성, 계급이 설정되지 않는 버그 수정 2022-08-12 02:25:12 +09:00
Hide_D 89fda44db8 game: 목우 상향, 무상성화 2022-08-10 23:53:19 +09:00
Hide_D fac8536095 fix: 도시 비중 계산식에서 '종사' 누락 2022-08-09 02:04:39 +09:00
Hide_D c79e65b6b7 misc: 아시아 명장전 유저장 스탯 수정 2022-08-08 21:38:02 +09:00
Hide_D 677e65ff6d dep: npm package update 2022-08-06 20:26:35 +09:00
Hide_D 0c7589d524 fix,misc: phan 검사 수준 복구 2022-08-05 23:45:31 +09:00
Hide_D da27ae2bad dep,refac: DTO를 composer 외부로 이동 2022-08-05 23:43:38 +09:00
Hide_D f8cd58bcb3 refac: conv_general_stat을 xlrd대신 opnepyxl로 변경
- 국가명 - 수뇌는 아직 테스트 안 해 보았음...
2022-08-03 00:53:41 +09:00
sarsandHide_D 3671a289b8 아시아 명장전 시나리오(비급) 추가 (#225)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/225
Reviewed-by: Hide_D <hided62@gmail.com>
Co-authored-by: sars <sarsntony@gmail.com>
Co-committed-by: sars <sarsntony@gmail.com>
2022-08-02 16:47:41 +09:00
Hide_D 48f4dbec50 misc: 부대편성 1000px 버튼의 위치를 명확히 2022-07-31 22:34:33 +09:00
Hide_D bdb29006e9 refac: 부대편성에서 1000px 모드 버튼을 좌하단으로 2022-07-31 22:20:29 +09:00
Hide_D 5ea324f103 fix: v-b-tooltip에서 undefined -> string type 초기화 생략 2022-07-31 20:34:18 +09:00
Hide_D 2f0cd32c18 fix: 부대 편성에서 부대장 집합 순서로 정렬 필요 2022-07-31 19:50:52 +09:00
Hide_D e8911d40df fix: 부대 편성에서 부대장과 다른 도시 표기가 안됨 2022-07-31 12:08:40 +09:00
Hide_D 89f173e7e3 fix: 베팅 최소 한도가 10이 아니라 1로 된 버그 수정 2022-07-30 21:13:00 +09:00
Hide_D b0ab3f6ace fix: css 누락, 로딩 누락 2022-07-30 20:48:31 +09:00
Hide_D 641af435d4 fix: 리셋 페이지 css 2022-07-30 20:45:27 +09:00
Hide_D 16a2f20af0 fix: 장수 카드에서 '남은 시간'이 제대로 표기 안됨 2022-07-30 20:16:08 +09:00
Hide_D 79734a6dcf fix: 부대명 변경이 아무에게나 보임 2022-07-30 19:44:30 +09:00
Hide_D 2e2ff1b150 feat: 감찰부에서 '이전', '다음' 버튼 2022-07-30 19:34:34 +09:00
Hide_D 5ce899ee6e fix: 장수 카드에 부상스탯 미반영 2022-07-30 14:25:23 +09:00
Hide_D e041080773 fix: 유산 포인트가 0이어도 동작 2022-07-30 12:15:07 +09:00
Hide_D f8448fbb51 fix: 자동 해산에 필요한 변수를 제공하지 않음 2022-07-30 10:34:40 +09:00
Hide_D 8defcd29a4 fix: 인자 오류 수정 2022-07-30 10:31:31 +09:00
Hide_D fba60df9d1 fix: binarysearch 상한 에러 2022-07-29 01:24:09 +09:00
Hide_D a4ff1f44ba build: source-map 활성화(디버그용) 2022-07-29 01:13:51 +09:00
Hide_D 7b75f4e01b misc: GeneralLiteCard grid 조정 2022-07-27 23:02:35 +09:00
Hide_D a9fc69e70f game: 벽력거 비용 약 상승, 목우 비용 하향 2022-07-27 22:52:02 +09:00
Hide_D a06c574327 fix: non vue page css 누락 2022-07-27 22:37:27 +09:00
Hide_D 420ae2f45b fix: 동일 부위 제한일 때, 무한히 알림오는 버그
- 의도대로라면 1턴마다 한번씩이어야함
2022-07-27 22:33:12 +09:00
Hide_D 850073a096 game: 유니크 낙찰 시 연장될 때 '상인' 전환
- 개최자와 낙찰자가 다를때에만
2022-07-27 22:30:22 +09:00
Hide_D e40aa88253 misc: 유니크 경매장에서 아이템 효과 툴팁 2022-07-27 22:21:25 +09:00
Hide_D ff92b0149a game: 벽력거 방어력 약 하향 2022-07-27 22:08:12 +09:00
Hide_D e6049a17a2 fix: 강행이 훈련,사기가 떨어지지 않는 문제 2022-07-27 21:59:29 +09:00
Hide_D 9bc1bc13f2 fix: 누락된 토너먼트 css 2022-07-27 21:57:58 +09:00
Hide_D b9cda08a4e fix: 천하통일 후에는 유산 포인트 사용 방지 2022-07-27 21:54:49 +09:00
Hide_D 4e2193fe6f fix: 불가침 파기시 header 수정 2022-07-27 21:49:45 +09:00
Hide_D 155af45378 refac: bootstrap.scss 분리 후 별도 빌드 2022-07-27 21:44:24 +09:00
Hide_D 66d6bbc772 feat: 경량 base.scss 2022-07-27 20:53:44 +09:00
Hide_D 066a6d4e6a build: bootstrap.scss 분리 2022-07-27 20:48:43 +09:00
Hide_D 94f5834b61 fix: 시나리오 생성시 성격에 class prefix 없음 2022-07-27 19:44:05 +09:00
Hide_D 947286bd09 game: npc 징병 쌀 기준 낮춤 2022-07-27 18:48:37 +09:00
Hide_D a0dee353b5 feat: 새 부대편성 페이지 (#223)
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/223
2022-07-27 18:01:41 +09:00
Hide_D 308b1f2348 fix: 감찰부 장수 변경시 tooltip 빈칸 버그 2022-07-26 23:56:50 +09:00
Hide_D 897780cf1c dep: package update 2022-07-26 23:32:43 +09:00
Hide_D 0f8a8011be fix: 중복되는 WarUnitTrigger의 priority 정정 2022-07-25 00:29:20 +09:00
Hide_D 7ebfd960b1 fix: 도시 관직 수치 조회 권한이 잘못됨 2022-07-24 17:23:20 +09:00
Hide_D 7b3d64996d fix: 감찰부 도시 관직명 누락 2022-07-24 17:15:06 +09:00
Hide_D e578a2f310 fix: 아이템 경매 버그 수정 2022-07-19 21:24:55 +09:00
Hide_D eecb4f699b game: 이미 같은 부위에 다른 유니크가 있는 경우, 경매 진행 방지 2022-07-17 22:34:05 +09:00
Hide_D 9f4f7a759e fix: 원조를 같은 국가로 지정할 수 있는 버그 수정 2022-07-17 16:40:40 +09:00
Hide_D 11a98eb184 fix: 장수 카드 부대 집합지가 항상 주황색 2022-07-17 16:40:35 +09:00
Hide_D ed0bc5e19f fix,refac: Nation/GetGeneralList에서 부대정보는 공개되어야 함 2022-07-17 01:37:07 +09:00
Hide_D 020a2d2668 fix: 감찰부 표기(*), 이름순 정렬 2022-07-16 16:39:12 +09:00
Hide_D 27cdd3ee4b misc: 구 감찰부 제거 2022-07-16 15:56:39 +09:00
Hide_D 43a95979e1 refac: 감찰부 vue3 재 작성 (#222)
- 장수 정보, 추가 정보 vue3 component
- b_battleCenter -> v_battleCenter

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/222
2022-07-16 15:49:23 +09:00
Hide_D 800106f9cb fix: 등용 버그 수정 시도 2022-07-14 11:40:30 +09:00
Hide_D e5c50e48d3 refac: defineComponent => vue3 setup 2022-07-13 22:37:37 +09:00
Hide_D 08e43bed71 fix: 서버 오픈 첫 턴에는 해산 불가 2022-07-13 22:07:25 +09:00
Hide_D 6773b8cddb fix: dependency 변경에 따른 오류 수정 2022-07-13 01:17:46 +09:00
Hide_D 23c030fd00 dep: package update 2022-07-12 21:47:01 +09:00
Hide_D d5e67bb16d refac: defineComponent => vue3 setup 2022-07-12 01:48:59 +09:00
Hide_D 188e3a0fa6 refac: defindComponent => vue3 setup 2022-07-12 01:26:33 +09:00
Hide_D b31ee022af refac: defineComponent => vue3 setup 2022-07-12 00:28:08 +09:00
Hide_D 87e063e03e fix,refac: 회의실에서 줄 바꿈이 표기 안되는 버그 수정 2022-07-12 00:09:58 +09:00
Hide_D 48fe26e4b1 refac: 숫자 입력기 재작성
- 입력마다 min, max clamp 작업 취소
2022-07-11 21:55:26 +09:00
Hide_D 88fcc64537 game: NPC 요양 기준 설정 가능 2022-07-11 20:23:55 +09:00
Hide_D d9beabbbbc feat: 발령시 장수 목록에 부대장 추가 표기 2022-07-10 21:58:30 +09:00
Hide_D 3da0a7d950 feat: 부대장인 경우 부대이름으로 검색 가능 2022-07-10 21:52:54 +09:00
Hide_D 50b1db75f0 fix: 본인이 아닌 수뇌자리에도 부대장 발령 표기 2022-07-10 21:27:34 +09:00
Hide_D 94bb96d208 feat: 부대장 발령 시 부대장 대신 부대 이름 표기 2022-07-10 20:50:33 +09:00
Hide_D 93490276fd misc: 집합에서 불필요한 조사 제거 2022-07-10 17:12:12 +09:00
Hide_D 73a7bf5a61 fix: 내정 도구 유니크가 동작하지 않는 버그 수정 2022-07-09 23:09:09 +09:00
Hide_D 8a1f8f8e2c fix: JsonString이 string->int auto casting하는 버그 수정 2022-07-09 13:02:13 +09:00
Hide_D 39c88c11c4 misc: 에러 확인을 위해 추가 메시지 2022-07-09 12:26:50 +09:00
Hide_D c2e956a639 misc: DTO 에러에서 name을 포함하여 알림 2022-07-09 12:13:15 +09:00
Hide_D 368f31d1fa fix: 유니크 옥션 인자 빠짐 수정 2022-07-09 12:12:15 +09:00
Hide_D d3390dc490 fix: 상인 등록 경매에서 warning 수정 2022-07-09 12:00:00 +09:00
Hide_D eb36b6a52f fix: vue script ts error 2022-07-08 21:47:13 +09:00
Hide_D be882000ad fix: 183년 이전 선포된 경우 공백지 출병을 시도하는 버그 수정 2022-07-08 15:53:37 +09:00
Hide_D 266c1c6a5b fix: 깃수 종료 시 열린 경매 자동 닫기 2022-07-07 22:00:12 +09:00
Hide_D 7864fe1e0f misc: 토너먼트, 베팅장 버튼을 약간 더 크게 2022-07-06 23:09:37 +09:00
Hide_D fe08fe0e2e fix: 누락된 스탯 유니크 설명 수정 2022-07-06 22:57:15 +09:00
Hide_D 87775a9471 game: 회피 발동시 피해 감소량을 1/5에서 1/6으로 버프 2022-07-06 22:52:20 +09:00
Hide_D 8089457aa8 game: 도구 유니크 밸런스 수정 2022-07-06 22:50:54 +09:00
Hide_D e443f92ddb fix: 초반 내정 기간에 NPC가 다중 선포가 가능한 버그 수정 2022-07-06 22:45:18 +09:00
Hide_D cb65666600 misc: 메인페이지 하단 바 높이를 약간 높임 2022-07-06 22:40:16 +09:00
Hide_D 6ed174e5dc game: 모반시도 삭제 2022-07-05 23:13:25 +09:00
Hide_D dd7f0ef3bf fix: 거병 커맨드가 막힌 없는 경우 사전 거병도 불가 2022-07-05 23:12:49 +09:00
Hide_D ec8e43a2a9 fix: 서버 목록에서 목록이 긴 경우에도 아이콘이 하나만 2022-07-05 23:05:11 +09:00
Hide_D a83b6b55cd feat: 천통국 내기 오픈시 메시지로 알림 2022-07-05 23:02:54 +09:00
Hide_D d43f15e096 fix: 빙의장도 사전 거병이 가능해야함 2022-07-05 22:39:40 +09:00
Hide_D e09fdefa68 feat,game: 사전 거병 기능 추가
- 건국은 게임 개시 2턴째부터 가능
2022-07-05 22:23:23 +09:00
Hide_D 2b483749bc game: 유산 포인트로 도시와 턴 시간을 동시에 설정할 수 없도록 변경 2022-07-05 20:18:02 +09:00
Hide_D 048d71920c fix: 변수명 수정 2022-07-05 19:29:58 +09:00
Hide_D 47366086d5 feat: 군주/외교권자에게 부대명 변경 기능 부여 2022-07-05 00:46:45 +09:00
Hide_D f9a73be82b game,refac: 토너먼트 진행 시간을 턴 시간에 맞춤(최소 5초) 2022-07-04 23:59:04 +09:00
Hide_D e7918469e5 refac: Util::valueFit을 Util::clamp로 2022-07-04 23:25:44 +09:00
Hide_D 687559a1a3 refac: 장수 삭제를 api로 이동 2022-07-02 02:43:10 +09:00
Hide_D 398c11e607 misc: 금액 선택에서 '+만' 활성화 2022-06-25 13:09:57 +09:00
Hide_D 191544d28b game: 삼모시네마틱유니버스 시나리오 업데이트 2022-06-25 13:06:25 +09:00
Hide_D 647c2439e3 feat: 유산 목록에서 로그를 더 가져올 수 있음 2022-06-25 12:22:25 +09:00
Hide_D da2a6f347a game: 도시 정보의 장수 순서를 실제 서버 실행 시간으로 변경 2022-06-24 21:49:02 +09:00
Hide_D dca341f35e fix: 연산단위 최소값 지정 2022-06-15 23:11:07 +09:00
Hide_D d38ddcd79e fix: 피장파장에서 모든 국가에(불가)가 나타나는 버그 2022-06-15 22:34:32 +09:00
Hide_D 03675349d8 fix: 사기진작 커맨드가 금소모를 하지 않음 2022-06-15 00:35:40 +09:00
Hide_D 72768ba7b5 fix: 경매 로그 마저 수정 2022-06-14 22:31:01 +09:00
Hide_D a5477db6b6 fix: 거래 완료시 메시지가 반대로 뜨는 버그 수정 2022-06-14 22:19:23 +09:00
Hide_D c146e8587b feat: 명장일람에 진행중인 유니크 경매 표시 2022-06-12 17:52:02 +09:00
Hide_D 24b65b0395 fix: 금쌀 경매장에 최근 로그 없음 2022-06-12 01:50:33 +09:00
Hide_D 2f42691d2b fix: 연감에 전투 시드가 겉으로 드러남 2022-06-11 15:09:35 +09:00
Hide_D ea619bd693 misc: 인사부에서 추방을 가장 아래로 2022-06-11 14:39:57 +09:00
Hide_D 35a56e74bb refac: 금쌀 경매장 UI 2022-06-11 03:53:30 +09:00
Hide_D 6fb2358161 refac: 유니크 경매 UI 수정 2022-06-10 02:07:05 +09:00
Hide_D a039fb871b fix: CreateManyNPC에서 모든 m장 사망년도가 같은 버그 수정 2022-06-10 00:49:47 +09:00
Hide_D a19da6cda5 fix: 경매장 갱신 버튼 2022-06-10 00:43:47 +09:00
Hide_D e5ba980865 fix: 종료된 유니크 경매 입찰시 버그 2022-06-10 00:38:34 +09:00
Hide_D f95ee8fab8 fix: 경매에서 이미 소지 수가 찬 유니크 획득 가능한 문제 수정 2022-06-09 22:28:51 +09:00
Hide_D 120706ef3f misc: 경매장 진입로를 금/쌀, 유니크로 2원화 2022-06-09 16:16:58 +09:00
Hide_D 58da20f276 fix: 동일 부위 유니크 소유시, '1턴' 연장하도록 수정 2022-06-09 15:49:13 +09:00
Hide_D 64af68e2d6 fix: 유니크 경매 시 종류 제한 계산 버그 2022-06-09 02:03:38 +09:00
Hide_D 76a8740644 fix: 유니크 경매시 10포인트 더 높아야 함 2022-06-09 01:53:19 +09:00
Hide_D 0863fafec0 fix: 경매가 시작후 3개월이 아니라 4개월로 설정됨 2022-06-09 01:49:22 +09:00
Hide_D 42579810a2 game: NPC의 이후 임관 확률을 낮춤 2022-06-09 01:30:08 +09:00
Hide_D 47e6b91b82 game: 시나리오 초기 생성 m장의 수명 증가 2022-06-09 01:25:41 +09:00
Hide_D dd38344319 feat,refac: 경매장 재설계, 유니크 경매장 구현 (#221)
- 경매장을 모든 입찰 기록이 남는 새로운 경매장 로직으로 변경
  - ng_auction, ng_auction_bid
    - DTO 사용
  - 상회입찰 시 개인메시지로 알림
- 기존의 '배경에서 조용히 이루어지는' 유니크 입찰을 공개된 유니크 경매장으로 변경
  - 종료 기간 명시
    - 종료 기간에 가까워질때 입찰하면 자동 연장
    - 최대 연장기간 있음
  - 유니크 제한인 경우 24턴 연장
  - 중원정세에서 '보물수배'로 알림

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/221
2022-06-09 01:21:55 +09:00
Hide_D 7964aa5f6b refac: phan warning 제거, nationStor변수 위치 2022-06-09 01:18:20 +09:00
Hide_D 85d372ecec refac: KakaoUtil 난수 random 타입 변경 2022-06-09 01:18:11 +09:00
Hide_D 6a2b27b875 fix: DummyGeneral에서 logger가 제대로 지정되었을 경우 대비 2022-06-09 01:18:06 +09:00
Hide_D 3b8a82fa42 game: 신규시나리오 누락 이벤트 추가 2022-06-07 01:56:21 +09:00
Hide_D 551e17b37b game: 삼모 시네마틱 유니버스 시나리오 2022-06-07 01:52:33 +09:00
Hide_D acccb74b4e feat: DTO에 toArrayExcept 추가 2022-06-04 21:29:47 +09:00
Hide_D 39be8fa4b8 fix: 감찰부 하단 버튼이 '돌아가기'인 버그 수정(임시) 2022-06-04 13:25:35 +09:00
Hide_D fc0c183ca3 game: 아이콘 크기를 30kb에서 50kb로 증량 2022-06-03 18:39:57 +09:00
Hide_D 329a461721 game: 방랑 커맨드 비활성화 2022-05-31 14:58:01 +09:00
Hide_D 35b178fe3c refac: DTO 구조 변경
- Converter - Constructor 관련 경고 수정
- JsonString 관련 의존성 제거, jsonFlag 지정
- DateTimeConveter에서 time format 지정
2022-05-29 00:44:28 +09:00
Hide_D 7464629597 feat: DTO에 Ignore 추가 2022-05-28 16:12:54 +09:00
Hide_D cb3982e57c feat: DTO에 DefaultValue, DefaultValueGenerator 추가 2022-05-28 15:53:06 +09:00
Hide_D 08eae297fd feat: DTO Convert 인자 버그 수정, DateTimeConverter 확장
- DateTimeConverter에 목표 Timezone 설정
2022-05-28 02:50:21 +09:00
Hide_D c46128ed3e feat: DTO에 DateTimeConveter 추가 2022-05-28 02:15:17 +09:00
Hide_D 78a55fb87a refac: 변경한 DTO에 따라 코드 수정
- Spatie/DataTransferObject 대비
  - MapFrom,MapTo -> RawName
  - Strict -> 항상
     - 심지어 raw type도 더 까다롭게
  - array에 MapConverter 적용
  - NullIsUndefined 적용
  - 빈 nullable arg자리에 null 강제 지정
- Vue3에 v-model.number 지정
  - input type="number" 기준
2022-05-22 22:39:28 +09:00
Hide_D 43a5162a15 feat: 직접 작성한 DTO 2022-05-22 16:53:56 +09:00
Hide_D cb5cb68bf4 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2022-05-19 02:49:25 +09:00
Hide_D b79a655d56 misc: git ignore 일부 수정 2022-05-19 02:48:52 +09:00
Hide_D 5b19c24f84 fix: 필살 비급 패치 누락 2022-05-18 17:28:38 +09:00
Hide_D e3716bda56 game: 입관했던 국가 재임관 가능 2022-05-18 01:41:37 +09:00
Hide_D b710a26b3e fix: 공백지에 건국이 완료된 경우 장수 생성이 되지 않는 버그 수정 2022-05-18 01:28:00 +09:00
Hide_D e5507e1e61 fix: 리셋 시 설문조사 목록을 초기화하지 않는 버그 수정 2022-05-18 01:00:18 +09:00
Hide_D 85f3d0b500 fix: 내부 이벤트 중 deterministic seed를 사용하지 않는 부분 수정 2022-05-18 00:55:43 +09:00
Hide_D 27811f4891 fix: nextBool 대신 nextFloat1 적은 부분 수정 2022-05-18 00:53:05 +09:00
Hide_D b22987f21b fix: 진행 중 $rng 호출 관련 버그 수정 2022-05-17 23:28:31 +09:00
Hide_D 8665838472 feat: RandUtil nextBool false 엔트로피 절약 2022-05-17 23:10:52 +09:00
Hide_D da3fb2c094 feat: nextBool에서 0.5인 경우 엔트로피 절약 2022-05-17 23:08:03 +09:00
Hide_D 485d696e85 fix: ts/util/simpleSerialize continue 누락 2022-05-17 23:03:25 +09:00
Hide_D 687f2b2edf fix: 게임 진행 도중 이민족이 발동되는 경우 edge case 수정
- 국가 중 하나가 이성 하나만 보유중인 경우
2022-05-17 23:02:11 +09:00
Hide_D 296a27a409 feat,refac: 남은 난수 생성값 추가 수정
- rand, mt_rand, Query rand() 쓰는 영역
- 거래장, 토너먼트는 남김
2022-05-17 23:01:00 +09:00
Hide_D c5ceff6fb5 feat,refac: 게임 로직 내 '랜덤'을 RandUtil을 활용하여 재설정
- 기존의 랜덤 코드는 deprecated 처리
- 서버 시작 시 랜덤하게 정해진 hiddenSeed를 활용
- 랜덤 생성 단위
  - 월 실행
  - 사령턴 실행 결과
  - 커맨드 실행 결과
  - 작위 보상
  - 부대장 생성
  - 유니크 획득 시도
  - 설문 조사
  - 장수 생성
  - NPC국 생성, NPC 생성, NPC의 토너먼트 베팅
  - 전투
  - 도시 점령
  - 자율 행동 선택
  - 랜덤 턴 변경
- 거래장, 토너먼트 등 구 랜덤 코드를 이용하는 잔여 코드 있음
2022-05-17 03:46:59 +09:00
Hide_D 2cb697f3dc feat: util/simpleSerialize 추가 2022-05-17 00:07:18 +09:00
Hide_D 56fd26935d game: 도기 주기를 5년에서 2년으로, 금액 일부 상향 2022-05-16 23:47:26 +09:00
Hide_D 002b528ef8 fix: 연감 순서 조정이 1000px에도 동작 2022-05-16 23:44:32 +09:00
Hide_D 1f60f5b3a4 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2022-05-16 23:42:54 +09:00
Hide_D cbafa4af61 feat: 연감에서 국가랭킹 위치 조절 기능 추가 2022-05-16 23:41:32 +09:00
Hide_D 19f936b6c0 feat: TopBackBar에 slot 추가 2022-05-16 23:20:11 +09:00
Hide_D 016f3c73e3 fix: 삭제된 General vote 필드 2022-05-16 15:19:34 +09:00
Hide_D 57541eca89 feat: 설문조사 시 최대 몇개까지 선택가능한지 안내 2022-05-16 02:27:34 +09:00
Hide_D b7e568fb98 fix: 설문 관련 메인 페이지 버그 2022-05-16 02:06:16 +09:00
Hide_D 438cff532b db: schema에서 더 이상 필요하지 않은 General.vote 제거 2022-05-16 02:04:09 +09:00
Hide_D 3f71490d14 fix: 메인 페이지에 최근 설문을 띄우도록 처리 2022-05-16 02:03:12 +09:00
Hide_D 2221a8c9bf fix: 설문에서 gold를 받아오지 못함 2022-05-16 01:54:46 +09:00
Hide_D 7255588bcc fix: 설문조사에서 multipleOptions 숫자 2022-05-16 01:52:39 +09:00
Hide_D c732bcddb1 misc: 설문 조사 페이지를 이전 2022-05-16 01:44:32 +09:00
Hide_D 9f363e46fc feat: 새 설문조사 모듈 UI 2022-05-16 01:41:10 +09:00
Hide_D 99242ac3d3 dep: css-color-names 추가 2022-05-16 01:03:20 +09:00
Hide_D 3d6aabda06 feat: 설문조사를 새 방식으로 구현 2022-05-15 20:55:14 +09:00
Hide_D d28a5e095a fix: 연감 페이지에서 지도가 다른 왕조 일람 역사 지도 에러 2022-05-15 18:09:18 +09:00
Hide_D 8104852abf fix: GET은 int를 arg로 받을 수 없음 2022-05-15 17:00:14 +09:00
Hide_D 459c108b13 fix: form input value가 string이 되어 number 검사에 실패 2022-05-15 16:52:23 +09:00
Hide_D d318ff7d90 dep: compose dependency 2022-05-15 02:23:27 +09:00
Hide_D 1371b84687 fix: Util::range에 yield type 지정 2022-05-14 23:48:18 +09:00
Hide_D 2cc679dcac feat: Util::generatorFromPairs 추가 2022-05-14 23:38:53 +09:00
Hide_D 04f5a1bbe1 feat: 새 설문 조사 Table 2022-05-14 23:00:01 +09:00
Hide_D 83c2fc918f misc: updateServer 시 좀 더 자세한 메시지 출력 2022-05-14 22:20:34 +09:00
Hide_D 63cfa5e298 refac: API 검증시 integer(int-like)에서 is_int로 강제 2022-05-14 22:13:51 +09:00
Hide_D 3e815691df feat: Validator에 stringArrray, int, float 추가 2022-05-14 22:03:55 +09:00
Hide_D 0fc0031574 dep: package update
- vue-eslint-parser의 9.0 업데이트는 에러로 인해 연기
2022-05-14 21:42:24 +09:00
Hide_D 6d335284ee feat: UniqueConst에 숨겨진 hiddenSeed 생성
- 이후 RNG에 사용
2022-05-13 23:45:14 +09:00
Hide_D 1a9010ac06 fix: 안보이는 with_skin 버튼 색 부활 2022-05-13 23:01:53 +09:00
Hide_D 4f40fa7813 misc: 턴 선택기 버튼 글씨 색 변경 2022-05-13 21:31:49 +09:00
Hide_D b7346b3816 misc: 턴 선택기의 주 버튼 색상 교체 2022-05-13 21:26:22 +09:00
Hide_D 400e47f616 fix: 토너먼트 베팅 시 최소 골드가 500이 아닌 버그 수정 2022-05-13 21:25:30 +09:00
Hide_D 5d499bbfbe fix: 서버 페이지에서 버튼을 bootstrap 버튼으로 변경 2022-05-13 20:27:31 +09:00
Hide_D e0d5c44184 fix: 아이템 버리기시, 조사 틀림 2022-05-13 18:01:31 +09:00
Hide_D f100998800 feat: 게임 시작 후, 거병/건국 기간, 출병 제한 기간을 안내 2022-05-11 02:22:40 +09:00
Hide_D 5bc31c91fa feat: 중원 정세에 메시지를 출력하는 Event Action 추가 2022-05-11 01:58:12 +09:00
Hide_D 4ca929d47d feat: 시작년도 기준으로 연월을 처리하는 Date Condition 추가 2022-05-11 01:50:05 +09:00
Hide_D 4ba43ea76a game: 기병의 출병시 병력 대상 전투력 5% 상향 2022-05-11 01:42:44 +09:00
Hide_D 34232a5504 game: 저지 발동시 숙련에 더해 명성도 추가 2022-05-11 01:36:54 +09:00
Hide_D 9b7464ab69 game: 필살 전투 특기가 '항상 최대 필살 대미지 계수'를 갖도록 수정
- 1.3 ~ 2.0에서 2.0 고정
2022-05-11 01:35:21 +09:00
Hide_D f003f38f74 fix: 일부 자동 조사가 적용되지 않는 코드 반영
- 유산 관리
  - 유니크 이름 받아오는 코드 일부 수정
- 인사부
2022-05-11 00:42:17 +09:00
Hide_D 91b2cecb19 feat: 유니크 입찰 시 첫번째 칸을 '공란'으로 두기 2022-05-11 00:32:03 +09:00
Hide_D 8c11661fb4 fix: 천통시 명장 일람에 유상포인트 최종 계산을 누락한 버그 수정 2022-05-11 00:26:47 +09:00
Hide_D 9aabe0442d game: 이미 같은 부위에 유니크를 가지고 있다면 유산 입찰 금지
- 이미 입찰한 같은 부위 유니크는 반환
2022-05-11 00:12:57 +09:00
Hide_D b463720512 fix: 아이템 파기 시 판매가 정정 2022-05-10 23:59:58 +09:00
Hide_D 6bc7c67589 feat: 장비매매로 유니크 판매시 전체 알림 2022-05-10 23:50:32 +09:00
Hide_D 443543d70f feat: 아이템 파기 추가 2022-05-10 23:46:39 +09:00
Hide_D 46a94b7816 feat: 명장 일람에 유산 소모량, 획득량 표기 2022-05-10 03:31:48 +09:00
Hide_D b2e297bbb3 feat: 유산 포인트 획득, 소모 정도를 동적으로 명장 일람 항목으로 기록
- 1월, 7월
- 베팅, 베팅 당첨을 소모/획득으로 분리
- 일단 유산 포인트 획득은 별도 분리
2022-05-10 03:26:34 +09:00
Hide_D 16906e960e feat: convertTupleArrayToDict 유틸리티 함수 생성 2022-05-10 02:37:50 +09:00
Hide_D 91bc734612 feat: 1, 7월마다 유산 포인트 rank_data 통계를 냄 2022-05-10 01:59:10 +09:00
Hide_D fa5546874a feat: RankColumn 유산 포인트 관련 추가 및 설명 보완 2022-05-09 23:58:15 +09:00
Hide_D 3921d159ef fix: 세력장수에서 rankColumn 대응 에러 수정 2022-05-09 22:33:16 +09:00
Hide_D cfcdc3149f fix: logExceptionByCustomHandler에서 echo 안하는 옵션 추가 2022-05-09 22:31:14 +09:00
Hide_D 717017fad5 misc: APIHelper에서 Exception과 Error를 상세 분리 2022-05-09 22:27:02 +09:00
Hide_D b8f957130d misc: 사용하지 않는 파일 제거 2022-05-09 22:02:54 +09:00
Hide_D 5824079b41 misc: 에러 로깅시 에러명에도 {ROOT}치환 2022-05-09 21:49:02 +09:00
Hide_D fbcfbb7156 fix: KVStorage deleteValue버그 수정 2022-05-09 21:42:17 +09:00
Hide_D b738984235 fix: 토너먼트 함수 인자에 맞게 수정 2022-05-09 21:40:20 +09:00
Hide_D c29333f8e0 fix: RankColumn 누락 부분 수정 2022-05-09 16:12:19 +09:00
Hide_D 123cf8d437 fix: error logger 수정 2022-05-09 16:08:53 +09:00
Hide_D 9293c4e480 feat: FatalError 대응 2022-05-09 03:42:51 +09:00
Hide_D fa5919aa1a Revert "refac: 에러 핸들링 방식 변경, FatalError 대응"
This reverts commit 80edfefdb1.
2022-05-09 03:40:54 +09:00
Hide_D 194f2bd2a5 refac: 에러 핸들링 방식 변경, FatalError 대응 2022-05-09 03:39:30 +09:00
Hide_D 0ae6584b02 fix: 아이템 치료의 우선순위가 낮아 '경상'치료가 안되는 버그 수정 2022-05-09 02:42:08 +09:00
Hide_D 397aa76e15 fix: KVStorage에서 Map으로 안 바뀐 코드 수정 2022-05-09 02:30:11 +09:00
Hide_D 43997b9117 fix: phan 메시지에 따라 수정
- array에 +=를 phan 알아듣기 쉽게 array_merge로
- Util::array_get이 더 이상 필요없으므로 null coalescing
- array로 tuple류를 반환하는 함수에 index를 포함하도록 변경
  - php intelephense에게는 현재 무효
- getPost 일부 값에 int 지정
- 아이템에 id property를 없앴으므로 관련 코드 제거
- enum은 array key로 사용할 수 없으므로 \Ds\Map으로 변경
- KakaoKey PhanRedefineClass 에러 우회
2022-05-09 01:25:12 +09:00
Hide_D de5fe818e6 fix: phan 출력 결과에 따라 처리
- switch에 변수를 정하는 경우 default에 throw
- Util::getPost에 일부 타입 강제
- array인 일부 값들에 PHPDoc 타입 지정
- Enum에 toString이 없으므로 value값 지정
- 사용하지 않는 use function 제거
2022-05-09 00:06:41 +09:00
Hide_D e3e315a068 dep: phan 2022-05-08 23:20:55 +09:00
Hide_D 5430a43589 fix: RankColumn 누락부분 수정 2022-05-08 23:11:15 +09:00
Hide_D a44172f509 refac: RankColumn enum 추가, General의 명장 일람 타입 변경 2022-05-08 23:09:27 +09:00
Hide_D 94bfd79afa fix: 감춰진 KVStorage의 initializer를 사용하는 코드 수정 2022-05-08 20:20:09 +09:00
Hide_D 2b4de68f0a refac: 더는 필요없어진 betting table 삭제 2022-05-08 20:15:03 +09:00
Hide_D 282b413553 refac: InheritPointManager를 Ds\Map으로 변경 2022-05-08 20:11:38 +09:00
Hide_D 5164585360 refac: KVStorage의 내부구조를 Ds\Map으로 변경 2022-05-08 20:10:04 +09:00
Hide_D f6642ecb0f dep: add php-ds 2022-05-08 19:23:24 +09:00
Hide_D 928042d71b feat: KVStorage에서 BackedEnum 지원 2022-05-08 13:30:16 +09:00
Hide_D 91cb3c4344 fix: 오타 수정 2022-05-08 13:15:28 +09:00
Hide_D eff79c4778 refac: 유산 포인트 파트를 별도의 Manager로 분리, enum 적용 2022-05-08 04:40:36 +09:00
Hide_D f7776d5067 dep: bootstrap5 warning 관련 버전 조정 2022-05-08 01:50:19 +09:00
Hide_D 68aae0bec1 misc: warning 제거 2022-05-08 01:44:16 +09:00
Hide_D cb7eb3b711 dep: package-updates 2022-05-08 01:36:06 +09:00
Hide_D 2a6b661285 fix: 연속 내정 성공 등, setInheritancePoint에 빙읮장을 누락한 버그 2022-05-07 15:26:52 +09:00
Hide_D d2ebf94453 fix: 빙의장이 베팅한 경우 베팅 성공으로 반영되지 않는 버그 수정 2022-05-07 15:24:16 +09:00
Hide_D 707f9ba7ce misc: 가입시 닉네임 변경 어려움을 알림 2022-05-07 15:16:38 +09:00
Hide_D 72e1d5e03b fix: 실제 코드 변경에 따라 의술을 1/3가 아니라 30%로 정정 2022-04-28 00:54:34 +09:00
Hide_D a612074aa4 fix: span, br 대신 div 2022-04-27 23:13:51 +09:00
Hide_D 86bbccb7f9 fix: 지도 렌더러에서 tooltip width가 덜 변경되도록 수정 2022-04-27 23:04:22 +09:00
Hide_D 11b7b57343 refac,feat: Global/ExecuteEngine
- 턴 실행
- 기존 proc.php와 유사
- 변경된 턴 있음 알림
2022-04-27 02:43:04 +09:00
Hide_D b682e53abe feat: General|Nation/GetGeneralLog 감찰부&내정보 로그 2022-04-27 01:40:09 +09:00
Hide_D ce877834cd feat: 장수 추가정보 카드
- 막대 구현
- 기존의 추가정보에 5턴분량 예턴 표기
2022-04-27 00:09:25 +09:00
Hide_D c69d171c3a feat: Nation/GeneralList 값 확장, 감찰부 2022-04-27 00:03:33 +09:00
Hide_D 1b24aa2421 feat: 기본 내정보 카드
- 아직 bar가 없음
2022-04-26 03:23:13 +09:00
Hide_D c61a4a70fc feat: Nation/GeneralList에 장수 기본 자료 일부 추가
- 내 정보, 감찰부에서 사용하는 자료
2022-04-26 03:14:48 +09:00
Hide_D bdefcc622f fix: Nation/GeneralList 권한 조정 2022-04-26 03:11:22 +09:00
Hide_D 67336323c2 fix: 세력장수에서 permission1(도시관직)도 보여야함. 2022-04-26 01:02:16 +09:00
Hide_D 3ac9e7c599 misc: 궁병 수비선제사격에서 선제 공격 로그를 단순하게 처리
- 상대방의 필살, 격노도 출력하지 않음
2022-04-26 00:39:36 +09:00
Hide_D 73f70fceff game,fix: 전추 치료 발동시 표기에 맞게 -50% -> -30% 2022-04-26 00:36:30 +09:00
Hide_D e353efc81d game: 궁병 수비 선제의 대미지를 50% 하향 2022-04-26 00:35:08 +09:00
Hide_D a37c427242 misc: auto500px, insertCustomCSS 누락된 페이지 정정 2022-04-26 00:33:54 +09:00
Hide_D d3c9b1f8a6 misc: 불필요한 베팅 import 코드 제거 2022-04-25 21:12:59 +09:00
Hide_D 0ca029babb fix: 천도 후 nationStaticInfo가 갱신되지 않는 버그 수정 2022-04-25 12:00:13 +09:00
Hide_D 492d113307 refac: 토너먼트 긴 switch 문을 assoc array로 변경 2022-04-25 02:33:37 +09:00
Hide_D f2bd48e452 fix,misc: 토너먼트 베팅 관련 잔여 코드 제거 2022-04-25 02:05:59 +09:00
Hide_D ddb7ee1ec2 fix: 국가 베팅장에서 '토너먼트'는 보여주지 않기로 2022-04-25 02:04:31 +09:00
Hide_D 7d62e94306 fix: 금 베팅시 betgold rankvar 누락 2022-04-25 01:51:42 +09:00
Hide_D 4961d76b96 fix: BettingDetail이 assocArray를 대응하지 못하는 버그 수정 2022-04-25 01:45:35 +09:00
Hide_D 12524e6e68 fix: 이제 BettingDetail 출력 변경
- BettingInfo의 candidate가 array를 보장하지 않음
- info가 html이 아니어도 출력
2022-04-25 01:30:54 +09:00
Hide_D 79f30ea275 refac: 토너먼트 베팅 세부 로직을 ng_betting으로 이동 (#218)
- 토너먼트 베팅을 betting 테이블 대신 Betting 모듈을 이용하는 형태로 변경
  - 이전 토너먼트 베팅 기록이 남음
  - 현재 이전 토너먼트 기록을 볼 수는 없음
- 베팅에 API/Betting/Bet 을 이용
- 토너먼트, 베팅 페이지를 Betting 모듈에 맞게 임시 조정
- 이전 버전과의 호환성을 위해 betting table과 betting 테이블에 초기값을 추가하는 로직은 남김
  - 이후 0.30이 되었을 때 제거

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/218
2022-04-25 01:06:32 +09:00
Hide_D 6ec2bf2880 fix: KVStorage에서 mb_strtolower를 제거하여 대소문자 구분 2022-04-25 00:39:13 +09:00
Hide_D 7708c26b71 refac: Betting 시작 코드를 모듈로 이동 2022-04-23 01:39:02 +09:00
Hide_D 4f300c6f82 refac: 구 jQuery Map wrapper를 Vue3 렌더러로 변경 2022-04-22 02:07:32 +09:00
Hide_D f4d67e759e refac: MapViewer에서 modelValue를 Legacy 버전과 맞춤 2022-04-22 00:36:25 +09:00
Hide_D e9b76217f7 feat: 임시용 cachedMap 출력 추가 2022-04-21 23:51:43 +09:00
Hide_D 85f801df4d feat: MapViewer와 API의 버전이 같을 때에만 지도 출력 2022-04-21 23:51:03 +09:00
Hide_D 01d5f2cda9 fix: 타 버전과 호환성을 위해, NO_SESSION 키워드 유지 2022-04-21 23:37:37 +09:00
Hide_D 601196e3f6 refac: APIHelper에 DummySession 적용, NO_LOGIN 구분 2022-04-21 23:33:08 +09:00
Hide_D cbf0be20a5 feat: SammoAPI 호출 prefix 변경 기능 제공 2022-04-21 23:17:23 +09:00
Hide_D e51421780e fix: 연감 철자 수정 2022-04-21 22:44:02 +09:00
Hide_D 2240282155 fix: 연감에서 폰트 크기 미 지정 2022-04-21 22:32:23 +09:00
Hide_D 5700b32c84 fix: 중원정보에서 분쟁 누락 2022-04-21 22:30:15 +09:00
Hide_D 4d72e0860e fix: AI에서 최근 전투 계산에서 외부 인력 계산 버그 2022-04-21 18:47:38 +09:00
Hide_D 994daf11d3 feat,refac: 중원 정보 페이지 2022-04-21 03:24:11 +09:00
Hide_D 79b92427aa fix: 중원정보 API에서 도시 목록이 id로 나오는 문제 2022-04-21 02:31:41 +09:00
Hide_D 6938c74014 feat: Global/GetDiplomacy 중원 정보 API 2022-04-21 02:28:17 +09:00
Hide_D 058a6e63f2 feat: Global/GetMap, Global/GetCachedMap 추가
-  지도를 가져오는 코드
- GetCahcedMap에서는 600초 단위 캐싱
  - history 필드에 최근 10건 표시
2022-04-21 01:24:07 +09:00
Hide_D 1be6b7a509 misc: Global/GetConst의 캐시 타입을 Public으로 변경 2022-04-21 01:18:12 +09:00
Hide_D ef532f0779 refac: API 캐시 컨트롤에서 max-age, public 지정 가능하도록 2022-04-21 01:17:20 +09:00
Hide_D 095a23df6d fix: get API의 경우 arg를 paramArg로 전환 2022-04-21 00:24:21 +09:00
Hide_D 7043521eaa fix: 연감 지도 수정 2022-04-20 22:40:07 +09:00
Hide_D 5eaafaeee6 fix: NPC 빙의 장수 목록 안보이는 버그 수정
- API/Global/GeneralList를 WithToken과 분리
2022-04-20 22:33:46 +09:00
Hide_D ec10949c64 fix: 걸그룹대전 스탯 수정 2022-04-20 21:56:31 +09:00
Hide_D 0e882cea17 feat: 걸그룹 대전 업데이트 2022-04-20 21:26:55 +09:00
Hide_D 4ad5cab37b feat,refac: vue3로 작성한 새 연감 페이지 (#217)
- 새 지도 렌더러 사용
- 새 연감 데이터 사용
- 500px 모드 지원
- Vue3 활용

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/217
2022-04-20 21:04:56 +09:00
Hide_D 2b6139050d feat: 커스터마이징 가능한 tooltip directive 2022-04-20 20:58:08 +09:00
Hide_D 14be16ce74 feat: Vue3로 작성된 지도 렌더러 (#216)
- 기존의 jQuery 기반 지도 렌더러를 Vue3로 재작성.
  - ajax로 호출하는 부분은 외부에서 처리하고, 다시 그리는 부분만 생성
  - 기능상으론 거의 동일.
- 일반 렌더러의 700px에, 500px모드용 모드 추가
  - 아이콘의 크기는 작아지지만, 글자 크기는 작아지지 않도록 조정

dep: vueuse, detect-it 추가

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/216
2022-04-20 03:34:12 +09:00
Hide_D c379ecf317 feat: 연감을 가져오는 API
- Global/GetHistory - 과거 기록. 캐싱 가능
- GetCurrentHistory - 현재 기록. 캐싱 불가
2022-04-18 03:05:08 +09:00
Hide_D eadbc774e3 misc: Global/GetConst session 모드 수정 2022-04-18 00:40:50 +09:00
Hide_D 90787cdc53 fix: 국가베팅 당첨자 없을 시, 버그 2022-04-17 21:40:24 +09:00
Hide_D 337733c3d3 fix,misc: 숙련 등급 입력시 음수인 경우에도 0으로 정상 처리 2022-04-17 21:19:35 +09:00
Hide_D b7048a4422 fix: NPC국 생성 시, 평균 기술력을 받아오지 못하는 문제 수정 2022-04-17 21:17:18 +09:00
Hide_D a036f1c4bb misc: 턴 선택기에서 커맨드 항목 높이를 조절 및 가운데 정렬 2022-04-15 20:11:21 +09:00
sars f9b1ab3ba7 배팅창에서 본선 장수들이 정해져있지 않을때 스탯을 출력하려는 워닝 수정 2022-04-14 19:17:40 -07:00
Hide_D 47599f000a refac: 명장일람, 명예의 전당 2022-04-15 02:36:42 +09:00
Hide_D efb1664443 refac: 감찰부 500px 모드 2022-04-15 02:00:51 +09:00
Hide_D 2c016621b6 game: 군주, 수뇌, 관직 전투력 상향 2022-04-14 01:28:44 +09:00
Hide_D f2a2b338cd fix: 전투 결과가 중복 기록되는 버그 수정 2022-04-13 03:05:23 +09:00
Hide_D 715a66fd35 fix: APIPathGen에서 NumVar, StrVar 동작 오류 2022-04-13 02:49:11 +09:00
Hide_D cc73f8c5d6 game: 베팅 포인트 수령 기준 변경
- 각 단계마다 총 수령액의 1/2씩, 잔여금은 1등상에게로
- 1등이 없는 경우 2등이 1등상+2등상 배분하여 수령
- 4개 선택시 각각, 56.25%, 25%, 12.5%, 6.25%를 나눠가짐
- 정답자가 전혀 없으면 포인트 환불
2022-04-13 02:33:58 +09:00
Hide_D 9b54b2b57d fix: 국가 베팅장에서 화면 이동 시에도 예전 기록이 남는 버그 수정 2022-04-13 02:04:00 +09:00
Hide_D fe4d095f21 game: 수뇌/관직 전투력 보정을 조정
- 수비시, 공격시가 아니라 항시 작동
- 군주: 공격 5%, 피해 -5%
- 참모: 공격 3%, 피해 -3%
- 무장 수뇌: 공격 3%
- 지장 수뇌: 피해 -3%
- 도시 관직: 공격 1.5%, 피해 -1.5%
2022-04-13 01:53:14 +09:00
Hide_D f67fa5c764 misc: JSON.parse 중 any인 것에 type 지정 2022-04-12 22:45:22 +09:00
Hide_D 06249f29cf game: 기병이 돌격 시 궁병 선제에 멈추도록 수정 2022-04-12 22:36:34 +09:00
Hide_D 242efc9ae7 fix: 궁병 수비시 선제로 인해 전투 로그가 두번 출력되는 버그 2022-04-12 22:27:48 +09:00
Hide_D c86572e6f3 game: 궁병에 회피 -5%p 2022-04-12 21:46:57 +09:00
Hide_D 03b458c1b2 game: 궁병에 '선제 사격' 추가
- 공격 시, 상대의 공격력을 1/2로 약화
- 수비 시, '선제 공격' 수행
   - 필살, 계략이 없는 일반 평타 공격
   - 공격자의 총 페이즈는 유지
2022-04-12 21:42:54 +09:00
Hide_D aa2e50366b feat: '선제 페이즈' 도입
- 일종의 '음수' 페이즈
   - 先 표기
   - 수비자 기준
- 내부의 currPhase가 변할 수 있도록 로직 변경
2022-04-12 21:40:49 +09:00
sarsandHide_D 657a47c9ad tournament (#214)
베팅창 QoL 개선

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/214
Co-authored-by: sars <sarsntony@gmail.com>
Co-committed-by: sars <sarsntony@gmail.com>
2022-04-10 17:46:28 +09:00
Hide_D 5d718bf4ea fix: 약탈발동에 저격특 효과 일부 코드가 남아 있던 버그 수정 2022-04-10 01:52:52 +09:00
Hide_D 082f847b1f game: 과실주(상성)를 대등한 병종에도 발동 2022-04-10 01:17:41 +09:00
Hide_D 54e4d74d0a fix: 장수 생성 페이지 너비 수정 2022-04-08 19:18:51 +09:00
Hide_D 1437d190e5 fix: 세력장수 이름 순에 NPC 정보 반영 2022-04-08 17:21:40 +09:00
Hide_D a95b26551c feat: 통합 세력 장수/암행부 페이지 (#213)
- ag-grid 기반
- 컬럼 사용자 정의 기능 제공
  - 컬럼 재정렬, 고정, 정렬 기능
  - 컬럼 상태 저장, 불러오기
  - 마지막 컬럼 재 사용
- 아이콘, 장수명 클릭 시 특수 기능 제공
  - 기본 세력 장수/암행부에서는 '감찰부'
- 추가 컬럼
  - 최근 전투
  - 전투 수
  - 승리 수
  - 살상률
- API/Nation/GeneralList 추가

Co-authored-by: hide_d <hided62@gmail.com>
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/213
2022-04-08 02:28:58 +09:00
Hide_D c96f6d9381 fix: 초성 오토마타에서 head가 제때 정리되지 않는 버그 2022-04-06 02:41:24 +09:00
Hide_D c7df50d899 fix: vue-tsc 에러 반영 2022-04-05 23:06:58 +09:00
sars 29619ada08 유산 소모에 (필요 포인트가 피보나치식으로 증가합니다) 메세지 추가 2022-04-04 09:51:37 -07:00
Hide_D 222c8a25a4 fix: 최근 실행 턴이 '선택 해제된 턴'을 따르지 않는 버그 수정 2022-04-04 21:40:54 +09:00
sars eac9b7c2e2 오타 수정 (@/SammoAPI에서 ./SammoAPI)로 2022-04-04 00:19:32 -07:00
Hide_D 31d6349d71 fix,refac: ETag 오기록 수정, Cache 설정을 WebUtil로 2022-04-04 01:44:35 +09:00
Hide_D b67f4daf3a refac: 장수 생성페이지 GetConst 활용 2022-04-03 23:14:19 +09:00
Hide_D 81b81d9036 feat: Global/GetConst API의 Store파트 2022-04-03 23:13:31 +09:00
Hide_D 2d06f368f8 refac: APICall에 타입 지정
- 비 undefined 타입에서 ?타입 호출 제거
- API 소속 type들을 defs/API/ 로 이동
- 모든 SammoAPI, SammoRootAPI 지정
2022-04-03 18:16:53 +09:00
Hide_D d0dc0f2bd1 fix: SammoAPICall에서 arg가 지정되어도 undefined가 가능한 버그 2022-04-03 17:15:36 +09:00
Hide_D e301c0fd3e refac: SammoAPI에 타입 지정 2022-04-03 02:17:14 +09:00
Hide_D 5879661267 refac, feat: API 호출 구조 재작성
- api.php에서 param path 강제
- api.php에서 GET param 허용
- SammoAPI 호출자를 axios에서 fetch 기반(ky)로 변경
- SammoAPI에서 단순 POST대신 REST에 따라 지정 가능하도록 재구성
- SammoAPI에서 NumVar, StrVar를 PathParam으로 변경하도록 변경
- API CallType들을 def/API로 분리 시작
  - 일부 API를 시험삼아 변경(login)
2022-04-02 23:31:05 +09:00
Hide_D ad1f070557 feat: 정적 변수를 반환하는 API 추가 Global/GetConst 2022-04-02 18:42:13 +09:00
Hide_D c20986b7b7 misc: BaseNation에서도 getInfo fallback 추가 2022-04-02 18:40:58 +09:00
Hide_D 153f425c99 refac: APIHelper 반환 값 정리 2022-04-02 18:39:47 +09:00
Hide_D 6eb202d4b2 misc: api cache max-age 단축
- 실제 캐시는 etag와 last-modified의 304 반환 활용
- http 2.0을 목표로하므로 큰 문제는 없을 것
2022-04-02 03:12:38 +09:00
Hide_D f7e46e16a3 fix: cache control에서 expires가 남는 문제 수정 2022-04-02 01:17:08 +09:00
Hide_D 36d7e22040 fix: api.php 설정이 전혀 동작하지 않던 문제 수정 2022-04-02 01:14:46 +09:00
Hide_D b24c4806f5 fix: APIHelper에서 tryCache가 잘못된 타입 지정인 버그 2022-04-01 23:27:04 +09:00
Hide_D 8ab79ad9f4 fix: 악질유저무쌍(비급) 시나리오 누락 2022-03-31 19:57:49 +09:00
Hide_D 4f4533e533 refac: linter 관련 설정 변경 및 적용, map_theme 변수 제거
- eslint에 prettier 조합
- prettierrc에 width 120, tabWidth 2
- gameStor->map_theme 제거
- map_theme, mapTheme를 GameConst::$mapName으로 대체
- eslint에서 vue/vue3-essential 대신 vue3-recommended 적용
  - vue/max-attributes-per-line 완화
  - vue/v-on-event-hyphenation 해제
  - vue/attribute-hyphenation 해제
- 일부 tsc import type warning 해결
- 일부 vue template type warning 해결
- 일부 vue SFC를 script setup으로 변경
  - TipTap
  - TopBackBar
  - BottomBackBar
  - BoardArticle
  - ProcessCity
2022-03-29 02:06:47 +09:00
Hide_D e569ffe8f4 build: eslint에서 vue/setup-compiler-macros 활성화
- 필요없어진 import 제거
2022-03-28 22:31:10 +09:00
Hide_D e09709651c fix: 지급률 계산식에서 부대장이 포함되는 버그 수정 2022-03-28 01:15:20 +09:00
Hide_D 39d7b6d55c fix: 1인국 n장 군주일때 발생하는 버그 수정
- 12월, 6월 지급률 계산 시
2022-03-28 01:11:05 +09:00
Hide_D 2b2a328062 game: 계략 성공률 한도를 50%로 제한 2022-03-27 16:55:47 +09:00
Hide_D 65e1495b44 fix: 베팅 대상에 들어가지 않은 국가가 성공 대상인 경우 버그
- purifyBettingKey에서 '해당 국가 없음' 에러를 내지 않도록 변경
2022-03-27 13:11:08 +09:00
Hide_D 3400f5843e game: 도기 판매시 국고와 개인 재산으로 반반씩 2022-03-27 03:54:37 +09:00
Hide_D e580691c1d fix: 백성동원 전략 사용시 국가 열전에 잘못된 양식으로 기록되는 버그 수정 2022-03-27 03:21:55 +09:00
Hide_D bb0e817943 game: 누락된 NPC 비중 수식 반영 2022-03-27 02:49:37 +09:00
Hide_D b7e4db6acd game: 랜임시 유저장 비중 보정
- NPC가 많은 국가가 기존보다 살짝 더 강해짐
- 여전히 유저 위주국가보다 불리
2022-03-27 00:50:03 +09:00
Hide_D 366fe5d613 refac: 시계부분을 분리하여 vue render 최적화 2022-03-27 00:06:40 +09:00
Hide_D 428f2706c3 feat: 최근 실행턴의 중복 관리를 개선 2022-03-26 23:44:01 +09:00
Hide_D 7f2b4596f7 fix: 사령부에서 최근 턴 저장 안되는 버그 수정 2022-03-26 23:30:20 +09:00
Hide_D ab9bdf3822 feat: 사령부의 턴 선택기에 고급 모드 적용 (#212)
- 사령부 턴 페이지를 vue3 setup 형태로 변경
- 턴 조작기 함수 중 공용 함수 분리
- 사령부 턴 조작기 코드 범위를 다시 조정
- 사령부 일반 모드, 고급 모드 이원화
- 사령부에서 다른 수뇌의 턴 '복사하기' 제공

Co-authored-by: Hide_D <hided62@gmail.com>
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/212
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2022-03-26 23:11:58 +09:00
Hide_D 585667dfe8 fix: 토너먼트 참가시 한쪽 슬롯이 가득 차면 입장이 닫히는 버그 2022-03-26 17:01:59 +09:00
Hide_D 151e6ed1f3 fix: 세력일람 확장에서 NPC 색상이 고정되는 버그 수정 2022-03-26 02:36:39 +09:00
Hide_D 0685d1caac fix: APIPathGen에서 Var 모드 사용시 에러 2022-03-26 00:04:18 +09:00
Hide_D f50ba83d31 fix: APIPathGen 호출 시 중간 경로 캐싱시 버그 수정 2022-03-25 23:50:41 +09:00
Hide_D 24c043386d refac: SammoAPI Path 정의에 NumVar, StrVar 추가 2022-03-25 23:29:10 +09:00
Hide_D 9d868cb2f4 refac: SammoAPI에서 인자, 반환 타입을 사전 지정 가능 2022-03-25 22:48:34 +09:00
Hide_D be308fdb4a fix: 불가침제의를 원래 의도대로 6개월로 변경 2022-03-24 10:59:04 +09:00
Hide_D 73a5f5287b fix: 중원 정보 표기 에러 수정 시도 2022-03-24 10:37:25 +09:00
Hide_D acafb15215 feat: 여러턴 예약을 ReserveBulkdCommand로 대체 2022-03-24 00:34:05 +09:00
Hide_D 79b9e1b22a fix: 연감 staticValues 중복 2022-03-23 23:51:29 +09:00
Hide_D 7ebdef3116 fix: 연감 표기를 staticValues export에 따라 수정 2022-03-23 23:45:29 +09:00
Hide_D a3fbaa0038 fix: 에러 로그에 따라 수정
- 임관, 하야 등에서 탑승 부대 해제
- 외교 서신 회수시 warning
- DummyGeneral에서 능력치 참조 시.
2022-03-23 23:40:50 +09:00
Hide_D fea2163a01 fix: 세력도시 style 문법 오류 2022-03-23 23:18:00 +09:00
Hide_D d55443968f fix: 세력도시 style 문법 오류 2022-03-23 23:15:11 +09:00
Hide_D b08a2681a2 feat: 세력도시에서 수입 정보 표기, NPC 색 누락분 수정 2022-03-23 23:13:28 +09:00
Hide_D 48af7e5e76 fix: 커맨드 선택시 '간이 복사' 기능이 남아있던 버그 2022-03-23 22:07:59 +09:00
Hide_D 98f48441c9 game: 내정 1% 감소 후, 세율 반영하도록 변경 2022-03-23 20:26:07 +09:00
Hide_D 65f2836379 game: 악질유저무쌍! 시나리오 추가 2022-03-23 20:20:48 +09:00
Hide_D 3548d4e939 feat: 턴 선택기를 재 작성 (#211)
- select form에서 유사 dialog 버튼 방식으로 변경
  - 카테고리마다 페이지 이동
- 일반 모드 / 고급 모드 분리
- 일반 모드에서는 턴별 즉시 설정
- 고급 모드에서는 드래그를 포함한 각종 기능 제공
  - 최근 실행 턴
  - 잘라내기, 복사하기, 붙여넣기
  - 반복하기
  - 비우기
  - 지우고 당기기, 뒤로 밀기
  - 보관하기, 보관한 턴 사용하기

Co-authored-by: Hide_D <hided62@gmail.com>
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/211
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2022-03-23 20:13:27 +09:00
Hide_D eb03f34a7e fix: 이미지 안올라가는 버그 수정 2022-03-23 01:01:47 +09:00
Hide_D 40b1a9fbdf build: bootstrap-vue-3
- tiptap/CustomImage 정의 문제 수정
- useToast() 관련 문제 수정
2022-03-20 18:37:38 +09:00
Hide_D 76a31acadc build: tsconfig 변경
- 반영된 룰에 맞게 import type 적용
2022-03-20 12:45:05 +09:00
Hide_D 0f71d786f7 fix: 빙의에서 장수 목록 보기를 사용할 수 없음 2022-03-20 12:14:20 +09:00
sars fec2508091 토너먼트 하이라이트와 토너먼트 액티브를 따로 변수로 저장 2022-03-16 23:10:54 -07:00
sars 4f087754e2 참가중일때만 토너먼트 액티브 설정 2022-03-16 20:24:12 -07:00
sars 520dbb23f2 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2022-03-16 12:12:46 -07:00
sars e8f2538510 토너먼트와 베팅장 하이라이트하기. (모바일에서 dropdown-item에서는 아직 적용 못함) 2022-03-16 12:09:29 -07:00
Hide_D fa6b271994 refac: schema.sql COLLATE, json_valid 지정 2022-03-16 23:44:12 +09:00
Hide_D c4aa6b4ffc game: 조기 은퇴 커맨드 추가 2022-03-16 01:30:47 +09:00
Hide_D 4bb1bac5d1 game: 유저장 자동 금쌀매매 기준 추가 변경 2022-03-16 00:38:18 +09:00
Hide_D 79815f99fc game: 유저장 자동 금쌀매매 기준 변경
- 3번 전멸하는 동안 필요한 금쌀을 모두 가지고 있을 경우 군량매매하지 않음
2022-03-16 00:02:38 +09:00
Hide_D 1342fb5cc1 game: 천통국 결정 시 자동으로 임관 금지 설정 2022-03-15 23:43:43 +09:00
Hide_D eae488b44f feat: BlockScoutAction Action 추가
- 모든 국가의 임관 설정을 임의 설정하는 이벤트 액션
2022-03-15 23:20:28 +09:00
sars 72200683fe serverNameWithCount를 serverName과 serverCnt로 나눔 2022-03-14 19:39:35 -07:00
sars c506d608c2 Merge branch 'devel' of ssh://storage.hided.net:2525/devsam/core into devel 2022-03-14 14:07:01 -07:00
sars 69348680d5 서버 이름과 횟수를 printStaticValue에 추가 2022-03-14 14:06:08 -07:00
Hide_D f6b359955d game,fix: 백이병 vs 정란, 벽력거 공격 상성 관련 문제 수정 2022-03-14 22:27:13 +09:00
Hide_D 0d4a68daea misc: gitignore update 2022-03-14 22:13:06 +09:00
sars dfff94f319 동결상태를 isLocked로 printStaticValue에 추가 2022-03-14 03:42:04 -07:00
sars 8cff55b5ed lastExecuted를 printStaticValues에 추가 2022-03-14 03:07:16 -07:00
Hide_D d61143c2ad misc: README 변경 2022-03-13 21:40:53 +09:00
Hide_D 1afe999beb Merge pull request 'feat: php vendor를 동적으로 구성하도록 변경' (#209) from no_php_vendor_code into devel
Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/209
2022-03-13 21:15:42 +09:00
Hide_D 0dd3def0d5 fix: composer 준비 전에도 j_install_status가 응답해야함 2022-03-13 21:03:39 +09:00
Hide_D 0a1d81be76 fix: Web UI로 초기 install이 불가능한 버그 수정 2022-03-13 20:16:54 +09:00
Hide_D 91ea0d1c2a build: 빌드 환경 재 설정
- lock에 따라 npm ci로 변경
- webpack build를 서버 내에서 하므로 dev dependency가 거의 없음
- webpack build에서 gateway build를 별도로 작성
2022-03-13 19:47:24 +09:00
Hide_D 5fe9136aa1 fix: 초기 index.php에서 vendor/autoload.php 검사 2022-03-13 19:06:31 +09:00
Hide_D 3ef91d3617 feat: install에서 composer update도 수행. update 기준 변경
- lock file을 git에 추가하였으므로, 이에 따름
2022-03-13 18:56:29 +09:00
Hide_D 0aa73c2f62 dep: vendor directory 제거 2022-03-13 18:33:09 +09:00
Hide_D d8ad26f83c dep: composer update 2022-03-13 16:55:04 +09:00
Hide_D 85a9f127bd fix: oauth_kakao에서 누락된 userID 반영 2022-03-13 13:46:13 +09:00
Hide_D edd5248d50 fix: COMPRESSED 타입 table 제거 2022-03-13 13:42:40 +09:00
Hide_D 892d13212d dep: npm package update. package-lock.json 해제 2022-03-13 01:59:55 +09:00
Hide_D 0ab485f122 feat: 해시 기반 간이 DRBG, 그에 기반한 RandUtil (#208)
기존의 Util 내의 함수는 mt_rand에 기반하고 있어서 일반적으론 충분하지만,
게임 내부에서 랜덤 값을 정교하게 제어하고 싶은 경우에는 적절하지 않았음.

따라서 직접 seed를 제어할 수 있는 난수생성기를 추가.
SHA512(seed || blockIdx) 의 형태로 동작하는 DRBG이며, FIPS 표준을 따르는 RNG는 아니지만 암호학적으로 안전한 형태로 구현함.

PHP, TS 두가지 형태로 구현.

Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/208
Co-authored-by: hide_d <hided62@gmail.com>
Co-committed-by: hide_d <hided62@gmail.com>
2022-03-12 23:53:16 +09:00
Hide_D c220b3d511 game: 정란 상성 공격력 상향, 차병 비용 절감 2022-03-12 20:11:36 +09:00
Hide_D 57bb22497e game: 이세계무쌍- 유저무쌍 멀티 유니버스 수정 2022-03-10 23:12:47 +09:00
Hide_D 1ae95ba4bc feat: NPC 추방,몰수, 고유메시지 빈도를 GameConst에서 조절 2022-03-10 23:11:56 +09:00
Hide_D 90b3684cdb game: 이세계무쌍 비급 시나리오 추가 2022-03-08 22:07:19 +09:00
Hide_D 15d6c427eb game: 이세계무쌍 시나리오 등록 2022-03-08 21:58:23 +09:00
Hide_D c68a428bf5 feat: 유닛테스트 준비 2022-03-03 00:16:01 +09:00
Hide_D a289b192e4 dep: typescript test 기반 추가 2022-03-02 23:31:32 +09:00
Hide_D 356f3af919 dep: phpunit 추가 2022-03-02 23:29:09 +09:00
Hide_D a660ec4cca fix: 커맨드 실행 조건 강제 탈출 조건을 잘못 작성하는 버그 수정 2022-03-01 12:29:21 +09:00
sars 4c9ddcb272 $general->getVar('nation')로 수정 2022-02-25 20:19:56 -08:00
sars 5131a36e20 general -> $general, 오타수정 2022-02-25 20:16:48 -08:00
sars 87c055563d 급하게 도기 코드 수정, 냐섭에서 테스트할 예정 2022-02-25 20:09:03 -08:00
sars 124c27cf17 동결풀기위해 도기템을 임시로 일단 주석처리함 2022-02-25 19:41:10 -08:00
Hide_D 4f0dbf0f92 feat: api.php 호출에서 path를 경로로 지정하는 방식 추가 2022-02-25 01:54:22 +09:00
Hide_D 6e24ca230d fix: 연감 static var 출력 버그 수정 2022-02-25 01:24:02 +09:00
Hide_D ac6e1d2525 fix: 1개 선택 베팅 보상 예측값이 잘못 설정된 버그 2022-02-24 00:22:27 +09:00
Hide_D 610b74d3a5 game: 표준 공백지 시나리오에 천통 베팅 추가 2022-02-24 00:15:36 +09:00
Hide_D 7f295aaacf fix: 탑 바 메뉴에서 세력도 제거. 세력도 페이지 제거 2022-02-23 23:55:18 +09:00
Hide_D a47669ff75 feat: 연감에 기존 세력도 기능 통합 2022-02-23 23:46:40 +09:00
Hide_D 9f84eb8d4d game,feat: 소비형 아이템 효율 상승, 환약 3회용으로 변경 2022-02-23 01:41:24 +09:00
Hide_D 5f36143b44 game: 숙련도로 얻는 유산 포인트 감소 2022-02-23 00:21:02 +09:00
Hide_D 2d491dd393 fix: 2회 이상 연속 전투에 성벽 전투가 포함된 경우 대인 사살이 계산되지 않는 버그 2022-02-22 23:55:13 +09:00
Hide_D 63845afdc3 fix: 재난 시 전체 이벤트 처리를 위해 column 추가 2022-02-22 15:39:43 +09:00
Hide_D 3cfcfff786 fix: 방어 대상에 crewtype 포함 2022-02-22 14:41:37 +09:00
Hide_D 9f801df5dc game: 평시 유니크 획득 확률 변경 2022-02-22 00:43:22 +09:00
Hide_D 21b8c6ea8f game: 작위 보상에서 아이템이 없는 사람이 받을 확률 대폭 증가 2022-02-22 00:28:35 +09:00
Hide_D 0807f9912c game: 반계도구 제거, 도구 밸런스 조정 2022-02-22 00:14:20 +09:00
Hide_D 90a71ba75d fix: 아이템 판매시 에러 방지 2022-02-20 15:31:52 +09:00
Hide_D 2e26244992 fix: 전투력보정에 unit이 제공되지 않음 2022-02-20 15:13:39 +09:00
Hide_D 8f1e713451 fix: 이벤트로 모든 장수의 지출이 0인 경우 대비 2022-02-20 14:57:56 +09:00
Hide_D b7b5c7b0da game: 아이템을 실제로 사용할 수 있도록 등록 2022-02-20 14:51:04 +09:00
Hide_D cb42813597 fix: 오타 수정 2022-02-20 05:11:26 +09:00
Hide_D 91c46f465b feat,game: 장비매매시 반응하는 트리거 추가, 판매시 국고에 추가되는 유니크 추가 2022-02-20 04:34:10 +09:00
Hide_D 435044dddd feat: 임의 커맨드용 트리거 추가 2022-02-20 04:30:05 +09:00
Hide_D cccf9968e7 game: 의술 유니크 추가 2022-02-20 04:10:34 +09:00
Hide_D f1e4185193 game: 비전투 커맨드 효율 유니크 추가 2022-02-20 04:02:35 +09:00
Hide_D dc538af7ba game,feat: 추가 숙련 trigger추가, 숙련 유니크 추가 2022-02-20 04:01:55 +09:00
Hide_D 574ca07afe game,feat: 조달 효율 변경 trigger 추가, 조달 유니크 추가 2022-02-20 04:01:03 +09:00
Hide_D f18b2ed1a5 fix: 능력치 유니크 오타 수정 2022-02-20 03:38:50 +09:00
Hide_D bc568e2083 game: 전투 특기 반영 유니크 도구 추가 2022-02-20 03:37:15 +09:00
Hide_D bffdf9d190 game: 1회저지, 회피저지 유니크 추가 2022-02-20 03:17:35 +09:00
Hide_D e7af4563a2 feat,game: 반계불가 처리 추가, 반계불가 유니크 추가 2022-02-20 03:16:46 +09:00
Hide_D 5fc5adb14d feat,game: 전투 중 약탈 추가, 약탈 유니크 추가 2022-02-20 03:13:03 +09:00
Hide_D f3ccf5e633 game: 경과 시간에 따라 변하는 유니크 추가 2022-02-20 03:12:17 +09:00
Hide_D 46cacc4a7d game,feat: 계략 커맨드 방어 유니크
- 계략 방어 확률에 보정 trigger 추가
2022-02-20 03:11:02 +09:00
Hide_D ac8edcee32 game: 회피 유니크 조절 2022-02-20 03:09:59 +09:00
Hide_D 919c44c727 game,feat: 전투력보정 관련 유니크 도구 추가
- 직접 전투력보정을 위한 WarUnitTrigger 추가
2022-02-20 03:08:24 +09:00
Hide_D 95921ae727 game: 사기, 훈련 유니크 수치 변경 2022-02-20 03:04:45 +09:00
Hide_D 134f043e9c refac: 아이템에 미사용 $id 값 제거 2022-02-19 23:54:03 +09:00
Hide_D a7a14a66a6 game: 벽력거를 진짜 무상성 병종으로 2022-02-19 17:55:29 +09:00
Hide_D 148d92164a refac: 장수 생성시 임관권유문 문구 변경
- coreui/vue 의존성 제거
2022-02-18 21:15:06 +09:00
Hide_D 5ea1b0bce4 refac: toast 출력을 bootstrap-vue-3 내부 toast로 변경
- component로 src 내부 ts/vue 사용 시도 중
2022-02-18 20:54:26 +09:00
Hide_D 65aefadcdc dep: package updates 2022-02-18 13:39:46 +09:00
Hide_D 1bc324fb9f fix: turnExecutionHelper env 관련 수정 2022-02-18 11:27:29 +09:00
Hide_D 28953ae1d9 fix: 토너먼트 참가 시점에서 생존여부 확인 2022-02-18 10:55:25 +09:00
Hide_D 3760e244a9 scenario: 천지비급에 '견고' 추가 2022-02-16 22:55:47 +09:00
Hide_D e86d755b69 scenario: 천지비급에서는 183년 이전에 항상 상인 2022-02-16 22:52:01 +09:00
Hide_D 6f560a1b34 버그 수정 2022-02-14 00:26:42 +09:00
Hide_D 6fe573ef7b fix: 토너먼트 실행 주기에서 초기화시 '수동'뜨는 문제 2022-02-08 20:39:49 +09:00
Hide_D 2a7baf020f misc: 연도 갱신 2022-02-06 12:08:58 +09:00
Hide_D 2e1815783a fix: 커맨드 세부 선택시 스탯 표기 오류 수정
- 통/무/지 순이어야함
2022-02-06 12:06:14 +09:00
Hide_DandGitea bab86c9f0b feat: 변경된 베팅 방식에 따라 결과 표기 2022-02-05 07:43:28 +00:00
Hide_DandGitea 2716e9af39 refac: 베팅 코드를 모듈로 2022-02-05 07:43:28 +00:00
Hide_DandGitea 9a303c4510 fix: n차 혼합 베팅 보상 수령이 하나만 되는 버그 수정 2022-02-05 07:43:28 +00:00
Hide_DandGitea e547971a6f feat: 베팅시 유산포인트 로그에 추가 2022-02-05 07:43:28 +00:00
Hide_DandGitea e9108ead86 feat: 베팅 보상 등록 2022-02-05 07:43:28 +00:00
Hide_DandGitea 6bbcb25138 feat(WIP): 베팅 보상 누락 수정 2022-02-05 07:43:28 +00:00
Hide_DandGitea 98462ca34d feat(WIP): 보상을 위한 Betting 모듈 추가 2022-02-05 07:43:28 +00:00
Hide_DandGitea 7939dd0b44 feat: 메인 페이지에 토너먼트 개최기간 표기 2022-02-05 07:43:27 +00:00
Hide_DandGitea 3d966ec076 fix: 베팅시 추가 포인트 부여 불가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 6afedb35df Revert "fix: 베팅시 추가 포인트 부여 불가"
This reverts commit 6fb4a1b274.
2022-02-05 07:43:27 +00:00
Hide_DandGitea cdac63e05a fix: 베팅시 추가 포인트 부여 불가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 8040cc28c4 fix: 베팅 순서 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea 264db40bdc fix: 베팅 관련 사소한 버그 수정
- 베팅이 없을 경우
- 베팅 동시 신청
2022-02-05 07:43:27 +00:00
Hide_DandGitea 2da1957c28 feat: 국가 베팅 ui 2022-02-05 07:43:27 +00:00
Hide_DandGitea 2297fa9c13 fix: NPCControl volar error 2022-02-05 07:43:27 +00:00
Hide_DandGitea 8175e76a77 build: warning 기준 변경
- 5MB, 3MB.......
2022-02-05 07:43:27 +00:00
Hide_DandGitea 2709dde8fa fix: template 2022-02-05 07:43:27 +00:00
Hide_DandGitea 7c518efba8 fix: volar error 수정
- getNPCColor 반환형
2022-02-05 07:43:27 +00:00
Hide_DandGitea b5fa2aef91 game: npc 색상 분리 2022-02-05 07:43:27 +00:00
Hide_DandGitea d2f6c34e85 fix: 베팅 시 key 정렬을 숫자 정렬로 2022-02-05 07:43:27 +00:00
Hide_DandGitea cd1ccfadaf fix: 세력일람 분석에서 자동수행턴을 반영하지 않는 버그 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea 8ff6bff252 game: 장수 생성시 종능이 부족하면 경고 2022-02-05 07:43:27 +00:00
Hide_DandGitea 52f6cb2f30 fix: 피장파장 시, 턴이 60턴이 늘어나는 것이 아니라 60턴이 되는 버그 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea e7af718a0f feat(WIP): 국가 베팅 '기능만' 구현 2022-02-05 07:43:27 +00:00
Hide_DandGitea d211c92bf8 fix: type react가 volar에서 문제를 일으킴 2022-02-05 07:43:27 +00:00
Hide_DandGitea 4acc988cfe feat(WIP): 베팅 개시 타입 변경
-candidate를 미리 추가.
-이를 통해 betting을 중립적으로 운용 가능
2022-02-05 07:43:27 +00:00
Hide_DandGitea 270f236f95 feat(WIP): OpenNationBetting에 보너스 상금 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 2da12bb71f fix: 이벤트 조건 오류 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea b479add03d misc: OpenNationBetting TODO 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea ca9db6dc18 Feat(WIP): OpenNationBetting Action 추가
- 시나리오 event에 추가
2022-02-05 07:43:27 +00:00
Hide_DandGitea 12c7c7b4ed feat(WIP): 이벤트 시나리오에서 불가능한 커맨드 지정 2022-02-05 07:43:27 +00:00
Hide_DandGitea e12c0e51c8 fix: 시나리오 모드에서 시작시점과 봉급월이 겹치는 경우 멈추는 문제 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea 6683c70195 fix: N장만 건국한 경우에 CreateManyNPC가 동작하지 않는 버그 수정 2022-02-05 07:43:27 +00:00
Hide_DandGitea aef1cbd201 fix: 봉급 계산에서 부대장 처리를 하지 않은 문제 수정
- 전체 지출 계산에만 실수 발생
2022-02-05 07:43:27 +00:00
Hide_DandGitea 06786aff28 feat(WIP): 이벤트 시나리오 준비 2022-02-05 07:43:27 +00:00
Hide_DandGitea 55439c268f feat: Event/Condition/RemainNation 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 3e4cf764c8 feat: 시나리오 event 포맷에서 target, priority 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 4e359f5eb9 feat: 도시 점령, 국가 멸망 시 트리거 추가 2022-02-05 07:43:27 +00:00
Hide_DandGitea 2ff3746df2 feat: event 테이블 준비 2022-02-05 07:43:27 +00:00
Hide_DandGitea 62982d7ffb feat(WIP): 베팅 상세 정보 반환 2022-02-05 07:43:27 +00:00
Hide_DandGitea ec49cdb6ad feat: Global/GetNationList 추가
- 세력일람의 데이터와 원칙적으로 동일
2022-02-05 07:43:27 +00:00
Hide_DandGitea 4b64827f20 feat(WIP): 베팅 관련 작업중 2022-02-05 07:43:27 +00:00
Hide_DandGitea 944c4cb564 dep: DTO 2022-02-05 07:43:27 +00:00
Hide_DandGitea db19655b60 feat: ng_betting 테이블 추가 2022-02-05 07:43:27 +00:00
Hide_D 1975f11338 fix: 이전 로그 키 정렬 기준이 int가 아니라 string인 버그 수정 2022-02-04 12:55:37 +09:00
Hide_D 59515d5276 game: 이민족 발동 관련 변경
- 이민족 멸망 후 타국가 임관
- 이민족 발동 시 명성을 평균치로
2022-01-21 01:00:31 +09:00
Hide_D fea9529bc8 fix: 내무부, 기밀 제한이 잘못된 버그 수정 2022-01-07 19:40:35 +09:00
4736 changed files with 84642 additions and 583822 deletions
-15
View File
@@ -1,15 +0,0 @@
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": 3,
"modules": false
}
]
],
"plugins": [
"lodash"
]
}
+16 -4
View File
@@ -3,20 +3,23 @@ module.exports = {
parser: "vue-eslint-parser", parser: "vue-eslint-parser",
"env": { "env": {
"browser": true, "browser": true,
"es2021": true "es2021": true,
'vue/setup-compiler-macros': true
}, },
ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'postcss.config.cjs', 'webpack.config.cjs', '*.js'], ignorePatterns: ['*.test.ts', '.eslintrc.cjs', 'postcss.config.cjs', 'webpack.config.cjs', '*.js'],
overrides: [{ overrides: [{
files: ['*.ts', '*.tsx', "*.vue"], files: ['*.ts', '*.tsx', "*.vue"],
}], }],
plugins: [ plugins: [
"@typescript-eslint" "@typescript-eslint",
"prettier"
], ],
extends: [ extends: [
"eslint:recommended", "eslint:recommended",
"plugin:vue/vue3-essential", "plugin:vue/vue3-recommended",
"plugin:@typescript-eslint/recommended" "plugin:@typescript-eslint/recommended",
"prettier",
], ],
parserOptions: { parserOptions: {
"sourceType": "module", "sourceType": "module",
@@ -27,6 +30,15 @@ module.exports = {
}, },
rules: { rules: {
'@typescript-eslint/no-floating-promises': 'error', '@typescript-eslint/no-floating-promises': 'error',
'vue/script-setup-uses-vars': 'error',
'vue/max-attributes-per-line': [
'warn',
{
singleline: 4, //prettier와 싸우지 말자
},
],
'vue/v-on-event-hyphenation': 'off', //vue3에선 필요없다고 생각
'vue/attribute-hyphenation': 'off', //vue3에선 필요없다고 생각
}, },
settings: { settings: {
'import/resolver': { 'import/resolver': {
+13 -9
View File
@@ -5,24 +5,21 @@
!.vscode/extensions.json !.vscode/extensions.json
/node_modules /node_modules
package-lock.json
# 체섭 ignore # 체섭 ignore
*.log *.log
logs/*.txt logs/*.txt
api_log.db
d_log/*.txt d_log/*.txt
d_log/*.zip d_log/*.zip
d_log/*.db
sess_* sess_*
*/logs/*.txt */logs/*.txt
*/logs/*/*.txt */logs/*/*.txt
*/logs/preserved */logs/preserved
err.txt err.txt
che/.htaccess
kwe/.htaccess
pwe/.htaccess
twe/.htaccess
hwe/.htaccess hwe/.htaccess
d_shared d_shared
@@ -34,6 +31,7 @@ d_pic/*.png
d_pic/*.webp d_pic/*.webp
d_pic/uploaded_image d_pic/uploaded_image
/dist_js
*/dist_misc/* */dist_misc/*
*/dist_js/* */dist_js/*
*/dist_css/* */dist_css/*
@@ -47,7 +45,7 @@ d_setting/*.php
*/d_setting/templates/*.php */d_setting/templates/*.php
!*.orig.php !*.orig.php
*/data/file_cache **/data/file_cache
**/old/* **/old/*
test.* test.*
@@ -59,11 +57,17 @@ test.*
/pya /pya
/twe /twe
/hwe/data
/vendor
phpinfo.php phpinfo.php
vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/*
*.sqlite3 *.sqlite3
ingame/js/* ingame/js/*
ingame/css/* ingame/css/*
gateway/js/* gateway/js/*
gateway/css/* gateway/css/*
*.db-journal
d_log/cachegrind.*
+12
View File
@@ -0,0 +1,12 @@
{
"extension": ["ts"],
"spec": "hwe/test-ts/**/*.test.ts",
"require": [
"ts-node/register",
"tsconfig-paths/register"
],
"node-option": [
"experimental-specifier-resolution=node",
"loader=ts-node/esm"
]
}
+2 -27
View File
@@ -15,8 +15,8 @@ return [
// Note that the **only** effect of choosing `'5.6'` is to infer // Note that the **only** effect of choosing `'5.6'` is to infer
// that functions removed in php 7.0 exist. // that functions removed in php 7.0 exist.
// (See `backward_compatibility_checks` for additional options) // (See `backward_compatibility_checks` for additional options)
"target_php_version" => '8.0', "target_php_version" => '8.2',
'backward_compatibility_checks ' => true, "minimum_target_php_version" => '8.2',
'minimum_severity' => \Phan\Issue::SEVERITY_NORMAL, 'minimum_severity' => \Phan\Issue::SEVERITY_NORMAL,
'file_list' => [ 'file_list' => [
@@ -28,8 +28,6 @@ return [
'hwe/_admin1_submit.php', 'hwe/_admin1_submit.php',
'hwe/_admin2.php', 'hwe/_admin2.php',
'hwe/_admin2_submit.php', 'hwe/_admin2_submit.php',
'hwe/_admin4.php',
'hwe/_admin4_submit.php',
'hwe/_admin5.php', 'hwe/_admin5.php',
'hwe/_admin5_submit.php', 'hwe/_admin5_submit.php',
'hwe/_admin7.php', 'hwe/_admin7.php',
@@ -39,21 +37,15 @@ return [
'hwe/a_emperior.php', 'hwe/a_emperior.php',
'hwe/a_genList.php', 'hwe/a_genList.php',
'hwe/a_hallOfFame.php', 'hwe/a_hallOfFame.php',
'hwe/a_history.php',
'hwe/a_kingdomList.php', 'hwe/a_kingdomList.php',
'hwe/a_npcList.php', 'hwe/a_npcList.php',
'hwe/api.php', 'hwe/api.php',
'hwe/a_status.php',
'hwe/a_traffic.php', 'hwe/a_traffic.php',
'hwe/a_vote.php',
'hwe/battle_simulator.php', 'hwe/battle_simulator.php',
'hwe/b_auction.php',
'hwe/b_battleCenter.php',
'hwe/b_betting.php', 'hwe/b_betting.php',
'hwe/v_chiefCenter.php', 'hwe/v_chiefCenter.php',
'hwe/b_currentCity.php', 'hwe/b_currentCity.php',
'hwe/v_nationStratFinan.php', 'hwe/v_nationStratFinan.php',
'hwe/b_diplomacy.php',
'hwe/b_genList.php', 'hwe/b_genList.php',
'hwe/b_myBossInfo.php', 'hwe/b_myBossInfo.php',
'hwe/b_myCityInfo.php', 'hwe/b_myCityInfo.php',
@@ -62,10 +54,7 @@ return [
'hwe/b_myPage.php', 'hwe/b_myPage.php',
'hwe/v_processing.php', 'hwe/v_processing.php',
'hwe/b_tournament.php', 'hwe/b_tournament.php',
'hwe/b_troop.php',
'hwe/c_auction.php',
'hwe/c_tournament.php', 'hwe/c_tournament.php',
'hwe/c_vote.php',
'hwe/func_auction.php', 'hwe/func_auction.php',
'hwe/func_command.php', 'hwe/func_command.php',
'hwe/func_converter.php', 'hwe/func_converter.php',
@@ -86,11 +75,9 @@ return [
'hwe/j_adjust_icon.php', 'hwe/j_adjust_icon.php',
'hwe/j_autoreset.php', 'hwe/j_autoreset.php',
'hwe/j_basic_info.php', 'hwe/j_basic_info.php',
'hwe/j_betting.php',
'hwe/j_board_article_add.php', 'hwe/j_board_article_add.php',
'hwe/j_board_comment_add.php', 'hwe/j_board_comment_add.php',
'hwe/j_board_get_articles.php', 'hwe/j_board_get_articles.php',
'hwe/j_die_immediately.php',
'hwe/j_diplomacy_destroy_letter.php', 'hwe/j_diplomacy_destroy_letter.php',
'hwe/j_diplomacy_get_letter.php', 'hwe/j_diplomacy_get_letter.php',
'hwe/j_diplomacy_respond_letter.php', 'hwe/j_diplomacy_respond_letter.php',
@@ -101,23 +88,13 @@ return [
'hwe/j_general_set_permission.php', 'hwe/j_general_set_permission.php',
'hwe/j_get_basic_general_list.php', 'hwe/j_get_basic_general_list.php',
'hwe/j_get_city_list.php', 'hwe/j_get_city_list.php',
'hwe/j_get_general_list.php',
'hwe/j_get_nation_general_list.php',
'hwe/j_get_select_npc_token.php', 'hwe/j_get_select_npc_token.php',
'hwe/j_get_select_pool.php', 'hwe/j_get_select_pool.php',
'hwe/j_image_upload.php',
'hwe/j_install_db.php', 'hwe/j_install_db.php',
'hwe/j_install.php', 'hwe/j_install.php',
'hwe/j_load_scenarios.php', 'hwe/j_load_scenarios.php',
'hwe/j_map_history.php',
'hwe/j_map.php', 'hwe/j_map.php',
'hwe/j_map_recent.php', 'hwe/j_map_recent.php',
'hwe/j_msg_contact_list.php',
'hwe/j_msg_decide_opt.php',
'hwe/j_msg_delete.php',
'hwe/j_msg_get_old.php',
'hwe/j_msg_get_recent.php',
'hwe/j_msg_submit.php',
'hwe/j_myBossInfo.php', 'hwe/j_myBossInfo.php',
'hwe/j_raise_event.php', 'hwe/j_raise_event.php',
'hwe/j_select_npc.php', 'hwe/j_select_npc.php',
@@ -126,13 +103,11 @@ return [
'hwe/j_set_my_setting.php', 'hwe/j_set_my_setting.php',
'hwe/j_set_npc_control.php', 'hwe/j_set_npc_control.php',
'hwe/j_simulate_battle.php', 'hwe/j_simulate_battle.php',
'hwe/j_troop.php',
'hwe/j_update_picked_general.php', 'hwe/j_update_picked_general.php',
'hwe/j_vacation.php', 'hwe/j_vacation.php',
'hwe/lib.php', 'hwe/lib.php',
'hwe/process_war.php', 'hwe/process_war.php',
'hwe/proc.php', 'hwe/proc.php',
'hwe/readme.php',
'hwe/recent_map.php', 'hwe/recent_map.php',
'hwe/select_general_from_pool.php', 'hwe/select_general_from_pool.php',
'hwe/select_npc.php', 'hwe/select_npc.php',
+5
View File
@@ -0,0 +1,5 @@
{
"tabWidth": 2,
"useTabs": false,
"printWidth": 120
}
+2 -1
View File
@@ -13,7 +13,7 @@
"/nya":true, "/nya":true,
"/pya":true, "/pya":true,
"/twe":true, "/twe":true,
}, },
"search.exclude": { "search.exclude": {
"e_lib/*":true, "e_lib/*":true,
@@ -29,4 +29,5 @@
"josa", "josa",
"sammo" "sammo"
], ],
"editor.tabSize": 4
} }
+1
View File
@@ -2,6 +2,7 @@
<html> <html>
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="color-scheme" content="dark">
<title>닫혀 있습니다.</title> <title>닫혀 있습니다.</title>
<script> <script>
setTimeout(function(){ setTimeout(function(){
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License The MIT License
Copyright (c) 2021 Hide_D, 62che Copyright (c) 2023 Hide_D, 62che
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
+4 -4
View File
@@ -26,20 +26,20 @@ Docker를 이용한 설치도 제공하고 있습니다.
## Docker를 이용한 설치 ## Docker를 이용한 설치
https://storage.hided.net/gogs/devsam/docker 를 참고해 주세요. https://storage.hided.net/gitea/devsam/docker 를 참고해 주세요.
## 수동 설치 ## 수동 설치
본 게임은 <code>git</code>을 이용한 업그레이드 시스템을 구현하였으므로, <code>git</code>이 필요합니다. 본 게임은 <code>git</code>을 이용한 업그레이드 시스템을 구현하였으므로, <code>git</code>이 필요합니다.
또한 웹 서비스 데몬을 운영중인 사용자(일반적으로 <code>www-data</code>, <code>apache</code>)에게 디렉토리 권한이 주어져야합니다. 또한 웹 서비스 데몬을 운영중인 사용자(일반적으로 <code>www-data</code>)에게 디렉토리 권한이 주어져야합니다.
### 다운로드 ### 다운로드
웹 데몬 user가 <code>www-data</code>인 경우 다음과 같이 입력하여 최신 배포버전과 이미지 파일을 얻을 수 있습니다. 웹 데몬 user가 <code>www-data</code>인 경우 다음과 같이 입력하여 최신 배포버전과 이미지 파일을 얻을 수 있습니다.
``` ```
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/core.git sudo -u www-data git clone https://storage.hided.net/gitea/devsam/core.git
sudo -u www-data git clone https://storage.hided.net/gogs/devsam/image.git sudo -u www-data git clone https://storage.hided.net/gitea/devsam/image.git
``` ```
> 이미지는 hook/git_hook.php을 통해 동기화되며, 서버 설치 과정에 이미지 갱신 키를 지정하는 것으로 '훼' 서버 업데이트 시 동기화됩니다. 이미지 서버가 게임 서버와 별개여도 동작하나, php와 git을 지원해야합니다. > 이미지는 hook/git_hook.php을 통해 동기화되며, 서버 설치 과정에 이미지 갱신 키를 지정하는 것으로 '훼' 서버 업데이트 시 동기화됩니다. 이미지 서버가 게임 서버와 별개여도 동작하나, php와 git을 지원해야합니다.
+5 -1
View File
@@ -8,5 +8,9 @@ require(__DIR__ . '/vendor/autoload.php');
if (!class_exists('\\sammo\\RootDB')) { if (!class_exists('\\sammo\\RootDB')) {
Json::dieWithReason('No DB'); Json::dieWithReason('No DB');
} }
$eParams = $_GET;
if(key_exists('path', $eParams)){
unset($eParams['path']);
}
APIHelper::launch(dirname(__FILE__)); APIHelper::launch(dirname(__FILE__), $_GET['path']??'', $eParams, true);
+18 -19
View File
@@ -8,47 +8,46 @@
], ],
"config": { "config": {
"platform": { "platform": {
"php": "8.0" "php": "8.3"
} }
}, },
"require": { "require": {
"brandonwamboldt/utilphp": "^1.1", "brandonwamboldt/utilphp": "^1.1",
"sergeytsalkov/meekrodb": "^2.3", "sergeytsalkov/meekrodb": "^2.5",
"league/plates": "^3.3", "league/plates": "^3.5",
"guzzlehttp/guzzle": "^6.3",
"monolog/monolog": "^1.23",
"firephp/firephp-core": "^0.4.0",
"vlucas/valitron": "^1.4", "vlucas/valitron": "^1.4",
"php-extended/php-tail": "^2.1", "php-extended/php-tail": "^5.0",
"pguardiario/phpuri": "^1.0", "symfony/lock": "^6.2",
"symfony/lock": "^4.1",
"ezyang/htmlpurifier": "^4.10", "ezyang/htmlpurifier": "^4.10",
"xemlock/htmlpurifier-html5": "^0.1.7", "xemlock/htmlpurifier-html5": "^0.1.7",
"catfan/medoo": "^1.5", "catfan/medoo": "^2.1",
"phan/phan": "*", "phan/phan": "^5.4",
"erusev/parsedown-extra": "^0.8.1", "nette/caching": "^3.3",
"nette/caching": "^3.0", "illuminate/database": "^10.0",
"illuminate/database": "^8.61", "illuminate/events": "^10.0",
"illuminate/events": "^8.61" "php-ds/php-ds": "^1.5",
"hided62/ldto": "^1.0",
"league/uri": "^6.8"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {
"sammo\\": [ "sammo\\": [
"d_setting",
"src/sammo" "src/sammo"
], ],
"kakao\\": [ "kakao\\": [
"d_setting",
"src/kakao" "src/kakao"
] ]
}, },
"classmap": [
"d_setting/"
],
"exclude-from-classmap": [ "exclude-from-classmap": [
"**/*.orig.php" "**/*.orig.php"
], ],
"files":[ "files":[
"f_config/config.php" "f_config/config.php"
] ]
},
"require-dev": {
"phpunit/phpunit": "^10.0"
} }
} }
Generated
+2945 -1400
View File
File diff suppressed because it is too large Load Diff
Executable → Regular
BIN
View File
Binary file not shown.
+15 -4
View File
@@ -81,23 +81,34 @@ a.just_link {
button.with_skin { button.with_skin {
padding: 0 4px; padding: 0 4px;
background-color: black; background-color: #191919;
color: white; color: white;
font-size: 14px; font-size: 14px;
border-top-color: gray;
border-left-color: gray;
border-right-color: black;
border-bottom-color: black;
} }
button.with_skin:disabled { button.with_skin:disabled {
background-color: #333333; background-color: #333;
} }
input.with_skin { input.with_skin {
background-color: black; background-color: #191919;
color: white; color: white;
font-size: 14px; font-size: 14px;
} }
input.with_skin[type=button], input.with_skin[type=submit]{
border-top-color: gray;
border-left-color: gray;
border-right-color: black;
border-bottom-color: black;
}
input.with_skin:disabled { input.with_skin:disabled {
background-color: #333333; background-color: #333;
} }
.font0 { .font0 {
+7 -2
View File
@@ -36,16 +36,21 @@ body {
height: 130px; height: 130px;
} }
#user_info button { #user_info .btn {
width: 200px; width: 200px;
height: 50px;
margin: 10px 50px; margin: 10px 50px;
padding: 10px;
} }
.center_ordered_items { .center_ordered_items {
text-align: center; text-align: center;
} }
.server-action{
padding-top: 16px;
padding-bottom: 16px;
}
.Entrance_ServerList { .Entrance_ServerList {
width: 800px; width: 800px;
height: 64px; height: 64px;
+35 -16
View File
@@ -49,7 +49,7 @@ function getFriendlyErrorType($type)
return "{$type}"; return "{$type}";
} }
function getExceptionTraceAsString($exception) function getExceptionTraceAsString(\Throwable $exception)
{ {
//https://gist.github.com/abtris/1437966 //https://gist.github.com/abtris/1437966
$rtn = ""; $rtn = "";
@@ -96,6 +96,8 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
$fdb = FileDB::db(ROOT . '/d_log/err_log.sqlite3', ROOT . '/f_install/sql/err_log.sql'); $fdb = FileDB::db(ROOT . '/d_log/err_log.sqlite3', ROOT . '/f_install/sql/err_log.sql');
$date = date("Ymd_His"); $date = date("Ymd_His");
$err = str_replace(ROOT, '{ROOT}', $err);
$errstr = str_replace(ROOT, '{ROOT}', $errstr);
$errpath = str_replace(ROOT, '{ROOT}', $errpath); $errpath = str_replace(ROOT, '{ROOT}', $errpath);
$trace = array_map(function (string $text) { $trace = array_map(function (string $text) {
return str_replace(ROOT, '{ROOT}', $text); return str_replace(ROOT, '{ROOT}', $text);
@@ -117,7 +119,7 @@ function logError(string $err, string $errstr, string $errpath, array $trace)
]); ]);
} }
function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline, array $errcontext=null) function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, int $errline)
{ {
if (!(error_reporting() & $errno)) { if (!(error_reporting() & $errno)) {
// This error code is not included in error_reporting, so let it fall // This error code is not included in error_reporting, so let it fall
@@ -133,11 +135,12 @@ function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, in
$errfile . ':' . $errline, $errfile . ':' . $errline,
getExceptionTraceAsString($e) getExceptionTraceAsString($e)
); );
return true;
} }
set_error_handler("\\sammo\\logErrorByCustomHandler"); set_error_handler("\\sammo\\logErrorByCustomHandler");
function logExceptionByCustomHandler(\Throwable $e) function logExceptionByCustomHandler(\Throwable $e, bool $withDie = true)
{ {
logError( logError(
@@ -147,32 +150,48 @@ function logExceptionByCustomHandler(\Throwable $e)
getExceptionTraceAsString($e) getExceptionTraceAsString($e)
); );
echo $e->getTraceAsString(); if($withDie){
throw $e; echo $e->getTraceAsString();
throw $e;
}
} }
set_exception_handler('\\sammo\\logExceptionByCustomHandler'); set_exception_handler('\\sammo\\logExceptionByCustomHandler');
function getAPIExecutorClass($path){ function checkForFatal()
{
$error = error_get_last();
if($error === null){
return;
}
if (($error["type"]??0) == E_ERROR) {
logErrorByCustomHandler($error["type"], $error["message"], $error["file"], $error["line"]);
}
}
static $basePath = __NAMESPACE__.'\\API\\'; register_shutdown_function("\\sammo\\checkForFatal");
if(is_string($path)){
} function getAPIExecutorClass($path)
else if(is_array($path)){ {
static $basePath = __NAMESPACE__ . '\\API\\';
if (is_string($path)) {
} else if (is_array($path)) {
$path = join('\\', $path); $path = join('\\', $path);
} } else {
else{
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님"); throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
} }
$classPath = str_replace('/', '\\', $basePath.$path); $classPath = str_replace('/', '\\', $basePath . $path);
if(class_exists($classPath)){ if (class_exists($classPath)) {
return $classPath; return $classPath;
} }
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님"); throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
} }
function buildAPIExecutorClass($type, string $rootPath, array $args):\sammo\BaseAPI{ function buildAPIExecutorClass($type, string $rootPath, array $args): \sammo\BaseAPI
{
$class = getAPIExecutorClass($type); $class = getAPIExecutorClass($type);
return new $class($rootPath, $args); return new $class($rootPath, $args);
} }
+4 -3
View File
@@ -10,6 +10,7 @@ require(__DIR__ . '/../vendor/autoload.php');
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<title>설치</title> <title>설치</title>
@@ -29,10 +30,10 @@ require(__DIR__ . '/../vendor/autoload.php');
<body> <body>
<div class="container"> <div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 설치</h1> <h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 설치</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-lg-center">
<div class="col col-12 col-md-10 col-lg-7"> <div class="col col-12 col-lg-10 col-lg-7">
<div class="card" id="db_form_card" style="display:none"> <div class="card" id="db_form_card" style="display:none">
<h3 class="card-header"> <h3 class="card-header">
설치(DB 설정) 설치(DB 설정)
+7 -9
View File
@@ -2,6 +2,11 @@
namespace sammo; namespace sammo;
if(!file_exists(__DIR__ . '/../vendor/autoload.php')){
http_response_code(503);
die('not_ready');
}
require(__DIR__ . '/../vendor/autoload.php'); require(__DIR__ . '/../vendor/autoload.php');
if (!class_exists('\\sammo\\RootDB')) { if (!class_exists('\\sammo\\RootDB')) {
@@ -12,18 +17,11 @@ if (!class_exists('\\sammo\\RootDB')) {
$rootDB = RootDB::db(); $rootDB = RootDB::db();
$rootDB->throw_exception_on_nonsql_error = false; $rootDB->addHook('run_failed', function ($params) {
$rootDB->nonsql_error_handler = function ($params) {
Json::die([
'step' => 'conn_fail'
]);
};
$rootDB->error_handler = function ($params) {
Json::die([ Json::die([
'step' => 'sql_fail' 'step' => 'sql_fail'
]); ]);
}; });
$memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member'); $memberCnt = $rootDB->queryFirstField('SELECT count(`NO`) from member');
if ($memberCnt == 0) { if ($memberCnt == 0) {
+7 -15
View File
@@ -90,19 +90,19 @@ if (
//기본 파일 생성 //기본 파일 생성
if (!file_exists(AppConf::getUserIconPathFS())) { if (!file_exists(AppConf::getUserIconPathFS())) {
mkdir(AppConf::getUserIconPathFS()); mkdir(AppConf::getUserIconPathFS(), 0775);
} }
if (!file_exists(ROOT . '/d_log')) { if (!file_exists(ROOT . '/d_log')) {
mkdir(ROOT . '/d_log'); mkdir(ROOT . '/d_log', 0775);
} }
if (!file_exists(ROOT . '/d_setting')) { if (!file_exists(ROOT . '/d_setting')) {
mkdir(ROOT . '/d_setting'); mkdir(ROOT . '/d_setting', 0775);
} }
if (!file_exists(ROOT . '/d_shared')) { if (!file_exists(ROOT . '/d_shared')) {
mkdir(ROOT . '/d_shared'); mkdir(ROOT . '/d_shared', 0775);
} }
} }
@@ -150,20 +150,12 @@ if (!file_exists(ROOT . '/d_setting/.htaccess')) {
$rootDB = new \MeekroDB($host, $username, $password, $dbName, $port, 'utf8mb4'); $rootDB = new \MeekroDB($host, $username, $password, $dbName, $port, 'utf8mb4');
$rootDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true; $rootDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
$rootDB->throw_exception_on_nonsql_error = false; $rootDB->addHook('run_failed', function ($args) {
$rootDB->nonsql_error_handler = function ($params) {
Json::die([ Json::die([
'result' => false, 'result' => false,
'reason' => 'DB 접속에 실패했습니다.' 'reason' => '에러.'. $args['error']
]); ]);
}; });
$rootDB->error_handler = function ($params) {
Json::die([
'result' => false,
'reason' => 'SQL을 제대로 실행하지 못했습니다. DB상태를 확인해 주세요.'
]);
};
$mysqli_obj = $rootDB->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨. $mysqli_obj = $rootDB->get(); //로그인에 실패할 경우 자동으로 dbConnFail()이 실행됨.
+17
View File
@@ -0,0 +1,17 @@
CREATE TABLE IF NOT EXISTS "api_log" (
"id" INTEGER NOT NULL,
"user_id" INTEGER NOT NULL,
"ip" TEXT NOT NULL,
"date" TEXT NOT NULL,
"path" TEXT NOT NULL,
"arg" TEXT,
"aux" TEXT,
PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE INDEX IF NOT EXISTS "by_date" ON "api_log" (
"date" DESC
);
CREATE INDEX IF NOT EXISTS "by_user" ON "api_log" (
"user_id" ASC,
"date" DESC
);
+16 -11
View File
@@ -31,8 +31,8 @@ CREATE TABLE `member` (
`NAME` VARCHAR(64) NOT NULL, `NAME` VARCHAR(64) NOT NULL,
`PICTURE` VARCHAR(64) NULL DEFAULT 'default.jpg', `PICTURE` VARCHAR(64) NULL DEFAULT 'default.jpg',
`IMGSVR` INT(1) NULL DEFAULT '0', `IMGSVR` INT(1) NULL DEFAULT '0',
`acl` TEXT NOT NULL DEFAULT '{}' COMMENT 'json', `acl` TEXT NOT NULL DEFAULT '{}' COLLATE 'utf8mb4_bin',
`penalty` TEXT NOT NULL DEFAULT '{}' COMMENT 'json', `penalty` TEXT NOT NULL DEFAULT '{}' COLLATE 'utf8mb4_bin',
`GRADE` INT(1) NULL DEFAULT '1', `GRADE` INT(1) NULL DEFAULT '1',
`REG_NUM` INT(3) NULL DEFAULT '0', `REG_NUM` INT(3) NULL DEFAULT '0',
`REG_DATE` DATETIME NOT NULL, `REG_DATE` DATETIME NOT NULL,
@@ -43,9 +43,12 @@ CREATE TABLE `member` (
UNIQUE INDEX `ID` (`ID`), UNIQUE INDEX `ID` (`ID`),
UNIQUE INDEX `EMAIL` (`EMAIL`), UNIQUE INDEX `EMAIL` (`EMAIL`),
UNIQUE INDEX `kauth_id` (`oauth_id`), UNIQUE INDEX `kauth_id` (`oauth_id`),
INDEX `delete_after` (`delete_after`) INDEX `delete_after` (`delete_after`),
CONSTRAINT `json1` CHECK (json_valid(`acl`)),
CONSTRAINT `json2` CHECK (json_valid(`penalty`))
) )
ENGINE=Aria DEFAULT CHARSET=utf8mb4; COLLATE='utf8mb4_general_ci'
ENGINE=Aria;
-- 로그인 로그 테이블 -- 로그인 로그 테이블
CREATE TABLE `member_log` ( CREATE TABLE `member_log` (
@@ -53,12 +56,14 @@ CREATE TABLE `member_log` (
`member_no` INT(11) NOT NULL, `member_no` INT(11) NOT NULL,
`date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
`action_type` ENUM('reg','try_login','login','logout','oauth','change_pw','make_general','access_server','delete') NOT NULL, `action_type` ENUM('reg','try_login','login','logout','oauth','change_pw','make_general','access_server','delete') NOT NULL,
`action` TEXT NULL DEFAULT NULL COMMENT 'JSON', `action` TEXT NULL DEFAULT NULL COLLATE 'utf8mb4_bin',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
INDEX `action` (`member_no`, `action_type`, `date`), INDEX `action` (`member_no`, `action_type`, `date`),
INDEX `member` (`member_no`, `date`) INDEX `member` (`member_no`, `date`),
CONSTRAINT `json` CHECK (json_valid(`action`))
) )
ENGINE=Aria DEFAULT CHARSET=utf8mb4; COLLATE='utf8mb4_general_ci'
ENGINE=Aria;
################### ###################
# KV storage # KV storage
@@ -69,9 +74,10 @@ CREATE TABLE if not exists `storage` (
`key` VARCHAR(40) NOT NULL, `key` VARCHAR(40) NOT NULL,
`value` TEXT NOT NULL, `value` TEXT NOT NULL,
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE INDEX `key` (`namespace`, `key`) UNIQUE INDEX `key` (`namespace`, `key`),
CONSTRAINT `json` CHECK (json_valid(`value`))
) )
COLLATE='utf8mb4_general_ci' COLLATE='utf8mb4_bin'
ENGINE=Aria; ENGINE=Aria;
CREATE TABLE `login_token` ( CREATE TABLE `login_token` (
@@ -86,5 +92,4 @@ CREATE TABLE `login_token` (
INDEX `by_date` (`user_id`, `expire_date`) INDEX `by_date` (`user_id`, `expire_date`)
) )
COLLATE='utf8mb4_general_ci' COLLATE='utf8mb4_general_ci'
ENGINE=Aria ENGINE=Aria;
;
-5
View File
@@ -61,11 +61,6 @@ class RootDB
if (self::$uDB === null) { if (self::$uDB === null) {
self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding); self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding);
self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true; self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
self::$uDB->error_handler = function () {
};
self::$uDB->throw_exception_on_error = true;
self::$uDB->throw_exception_on_nonsql_error = true;
} }
return self::$uDB; return self::$uDB;
} }
+58
View File
@@ -165,3 +165,61 @@
background: url('_tK_gameImagePath_/map/pokemon_v1/back_pal8.png') no-repeat; background: url('_tK_gameImagePath_/map/pokemon_v1/back_pal8.png') no-repeat;
background-size: 700px 500px; background-size: 700px 500px;
} }
/*CR 지도*/
.map_theme_cr .map_bglayer1{
background: url('_tK_gameImagePath_/map/cr/bg-fs8.png') no-repeat;
background-size: 700px 500px;
}
.map_theme_cr.map_detail .city_base .city_bg {
background-image: none !important;
width: 39.5px !important;
height: 39.5px !important;
left: 1px !important;
top: -4px !important;
opacity: 0.5;
}
.map_theme_cr.map_detail.small_width_map .city_base .city_bg {
background-image: none !important;
width: 28.5px !important;
height: 28.5px !important;
left: 6px !important;
top: 4px !important;
opacity: 0.5;
}
.map_theme_cr.map_detail .city_bg.bFF0000 { background-color: #FF0000; }
.map_theme_cr.map_detail .city_bg.b800000 { background-color: #800000; }
.map_theme_cr.map_detail .city_bg.bA0522D { background-color: #A0522D; }
.map_theme_cr.map_detail .city_bg.bFF6347 { background-color: #FF6347; }
.map_theme_cr.map_detail .city_bg.bFFA500 { background-color: #FFA500; }
.map_theme_cr.map_detail .city_bg.bFFDAB9 { background-color: #FFDAB9; }
.map_theme_cr.map_detail .city_bg.bFFD700 { background-color: #FFD700; }
.map_theme_cr.map_detail .city_bg.bFFFF00 { background-color: #FFFF00; }
.map_theme_cr.map_detail .city_bg.b7CFC00 { background-color: #7CFC00; }
.map_theme_cr.map_detail .city_bg.b00FF00 { background-color: #00FF00; }
.map_theme_cr.map_detail .city_bg.b808000 { background-color: #808000; }
.map_theme_cr.map_detail .city_bg.b008000 { background-color: #008000; }
.map_theme_cr.map_detail .city_bg.b2E8B57 { background-color: #2E8B57; }
.map_theme_cr.map_detail .city_bg.b008080 { background-color: #008080; }
.map_theme_cr.map_detail .city_bg.b20B2AA { background-color: #20B2AA; }
.map_theme_cr.map_detail .city_bg.b6495ED { background-color: #6495ED; }
.map_theme_cr.map_detail .city_bg.b7FFFD4 { background-color: #7FFFD4; }
.map_theme_cr.map_detail .city_bg.bAFEEEE { background-color: #AFEEEE; }
.map_theme_cr.map_detail .city_bg.b87CEEB { background-color: #87CEEB; }
.map_theme_cr.map_detail .city_bg.b00FFFF { background-color: #00FFFF; }
.map_theme_cr.map_detail .city_bg.b00BFFF { background-color: #00BFFF; }
.map_theme_cr.map_detail .city_bg.b0000FF { background-color: #0000FF; }
.map_theme_cr.map_detail .city_bg.b000080 { background-color: #000080; }
.map_theme_cr.map_detail .city_bg.b483D8B { background-color: #483D8B; }
.map_theme_cr.map_detail .city_bg.b7B68EE { background-color: #7B68EE; }
.map_theme_cr.map_detail .city_bg.bBA55D3 { background-color: #BA55D3; }
.map_theme_cr.map_detail .city_bg.b800080 { background-color: #800080; }
.map_theme_cr.map_detail .city_bg.bFF00FF { background-color: #FF00FF; }
.map_theme_cr.map_detail .city_bg.bFFC0CB { background-color: #FFC0CB; }
.map_theme_cr.map_detail .city_bg.bF5F5DC { background-color: #F5F5DC; }
.map_theme_cr.map_detail .city_bg.bE0FFFF { background-color: #E0FFFF; }
.map_theme_cr.map_detail .city_bg.bFFFFFF { background-color: #FFFFFF; }
.map_theme_cr.map_detail .city_bg.bA9A9A9 { background-color: #A9A9A9; }
+2 -1
View File
@@ -14,13 +14,14 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
[$turntime, $tnmt_time] = $gameStor->getValuesAsArray(['turntime','tnmt_time']); [$turntime, $tnmt_time] = $gameStor->getValuesAsArray(['turntime','tnmt_time']);
$plock = $db->queryFirstField('SELECT plock FROM plock'); $plock = $db->queryFirstField('SELECT plock FROM plock WHERE `type` ="GAME"');
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title>삼국지 모의전투 HiDCHe</title> <title>삼국지 모의전투 HiDCHe</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?> <?=WebUtil::printCSS('../d_shared/common.css')?>
+6 -6
View File
@@ -50,9 +50,9 @@ switch ($btn) {
$db->update('general', [ $db->update('general', [
'turntime' => $db->sqleval('DATE_SUB(turntime, INTERVAL %i MINUTE)', $minute) 'turntime' => $db->sqleval('DATE_SUB(turntime, INTERVAL %i MINUTE)', $minute)
], true); ], true);
$db->update('auction', [ $db->update('ng_auction', [
'expire' => $db->sqleval('DATE_SUB(expire, INTERVAL %i MINUTE)', $minute) 'close_date' => $db->sqleval('DATE_SUB(close_date, INTERVAL %i MINUTE)', $minute)
], true); ], 'finished = 0');
if ($locked) { if ($locked) {
unlock(); unlock();
} }
@@ -78,9 +78,9 @@ switch ($btn) {
$db->update('general', [ $db->update('general', [
'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute) 'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
], true); ], true);
$db->update('auction', [ $db->update('ng_auction', [
'expire' => $db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute) 'close_date' => $db->sqleval('DATE_ADD(close_date, INTERVAL %i MINUTE)', $minute)
], true); ], 'finished = 0');
if ($locked) { if ($locked) {
unlock(); unlock();
} }
+1 -2
View File
@@ -19,6 +19,7 @@ $admin = getAdmin();
<head> <head>
<title>게임관리</title> <title>게임관리</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?=WebUtil::printCSS('../d_shared/common.css')?> <?=WebUtil::printCSS('../d_shared/common.css')?>
@@ -40,8 +41,6 @@ $admin = getAdmin();
<tr> <tr>
<td width=110 align=right>시작시간변경</td> <td width=110 align=right>시작시간변경</td>
<td width=285><input type=text size=20 maxlength=20 style=color:white;background-color:black;text-align:right; name=starttime value='<?=substr($admin['starttime'], 0, 19)?>'><input type=submit name=btn value=변경1></td> <td width=285><input type=text size=20 maxlength=20 style=color:white;background-color:black;text-align:right; name=starttime value='<?=substr($admin['starttime'], 0, 19)?>'><input type=submit name=btn value=변경1></td>
<td width=110 align=right>현재도시훈사</td>
<td width=285><?=$admin['city_rate']?></td>
</tr> </tr>
<tr> <tr>
<td width=110 align=right>최대 장수</td> <td width=110 align=right>최대 장수</td>
+2 -22
View File
@@ -72,29 +72,9 @@ switch ($btn) {
case "30분턴": $turnterm = 30; break; case "30분턴": $turnterm = 30; break;
case "60분턴": $turnterm = 60; break; case "60분턴": $turnterm = 60; break;
case "120분턴": $turnterm = 120; break; case "120분턴": $turnterm = 120; break;
default: throw new \Exception("알 수 없는 턴 기간");
} }
$oldunit = $admin['turnterm'] * 60; ServerTool::changeServerTerm($turnterm);
$unit = $turnterm * 60;
$unitDiff = $unit / $oldunit;
$servTurnTime = new \DateTimeImmutable($admin['turntime']);
foreach ($db->query('SELECT no,turntime FROM general') as $gen) {
$genTurnTime = new \DateTimeImmutable($gen['turntime']);
$timeDiff = TimeUtil::DateIntervalToSeconds($genTurnTime->diff($servTurnTime));
$timeDiff *= $unitDiff;
$newGenTurnTime = $servTurnTime->add(TimeUtil::secondsToDateInterval($timeDiff));
$db->update('general', [
'turntime'=>$newGenTurnTime->format('Y-m-d H:i:s.u')
], 'no=%i', $gen['no']);
}
$turn = ($admin['year'] - $admin['startyear']) * 12 + $admin['month'] - 1;
$starttime = $servTurnTime->sub(TimeUtil::secondsToDateInterval($turn * $unit))->format('Y-m-d H:i:s');
$starttime = cutTurn($starttime, $turnterm, false);
$gameStor->turnterm = $turnterm;
$gameStor->starttime = $starttime;
pushGlobalHistoryLog(["<R>★</>턴시간이 <C>$btn</>으로 변경됩니다."]);
break; break;
} }
+15 -51
View File
@@ -20,6 +20,7 @@ $db = DB::db();
<head> <head>
<title>회원관리</title> <title>회원관리</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -48,54 +49,25 @@ $db = DB::db();
<font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b> <font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b>
</td> </td>
<td width=105 rowspan=12> <td width=105 rowspan=12>
<?php <select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:14px'>
<?php
$generalList = $db->query('SELECT `no`, `name`, npc, `block` FROM general ORDER BY npc, binary(`name`)');
echo " foreach ($generalList as $general) {
<select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:14px'>"; $style = "style=;";
$generalList = $db->query('SELECT `no`, `name`, npc, `block` FROM general ORDER BY npc, binary(`name`)'); if ($general['block'] > 0) {
$style .= "background-color:red;";
foreach ($generalList as $general) {
$style = "style=;";
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
if ($general['npc'] >= 2) {
$style .= "color:cyan;";
} elseif ($general['npc'] == 1) {
$style .= "color:skyblue;";
}
echo "
<option value={$general['no']} $style>{$general['name']}</option>";
}
echo "
</select>
</td>
<td width=100 align=center>아이템 지급</td>
<td width=504>
<select name=weapon size=1 style='color:white;background-color:black;font-size:14px'>";
foreach (GameConst::$allItems as $itemCategories) {
foreach ($itemCategories as $item => $cnt) {
if ($cnt == 0) {
continue;
} }
$itemObj = buildItemClass($item);
if ($itemObj->isBuyable()) { $npcColor = getNPCColor($general['npc']);
continue; if ($npcColor !== null) {
$style .= "color:{$npcColor};";
} }
echo "<option value={$general['no']} $style>{$general['name']}</option>";
} }
} ?>
for ($i = 0; $i < 27; $i++) {
echo "
<option value={$i}>{$i}</option>";
}
?>
</select> </select>
<input type=submit name=btn value='무기지급'>
<input type=submit name=btn value='책지급'>
<input type=submit name=btn value='말지급'>
<input type=submit name=btn value='도구지급'>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -109,10 +81,6 @@ $db = DB::db();
<td align=center>강제 사망</td> <td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td> <td><input type=submit name=btn value='강제 사망'></td>
</tr> </tr>
<tr>
<td align=center>이벤트</td>
<td><input type=submit name=btn value='특기 부여'><input type=submit name=btn value='공헌치1000'><input type=submit name=btn value='경험치1000'></td>
</tr>
<tr> <tr>
<td align=center>이벤트2</td> <td align=center>이벤트2</td>
<td><input type=submit name=btn value='보숙10000'><input type=submit name=btn value='궁숙10000'><input type=submit name=btn value='기숙10000'><input type=submit name=btn value='귀숙10000'><input type=submit name=btn value='차숙10000'></td> <td><input type=submit name=btn value='보숙10000'><input type=submit name=btn value='궁숙10000'><input type=submit name=btn value='기숙10000'><input type=submit name=btn value='귀숙10000'><input type=submit name=btn value='차숙10000'></td>
@@ -121,10 +89,6 @@ $db = DB::db();
<td align=center>접속제한</td> <td align=center>접속제한</td>
<td><input type=submit name=btn value='접속 허용'><input type=submit name=btn value='접속 제한'></td> <td><input type=submit name=btn value='접속 허용'><input type=submit name=btn value='접속 제한'></td>
</tr> </tr>
<tr>
<td align=center>턴 시각 설정</td>
<td><input type=submit name=btn value='00턴'><input type=submit name=btn value='랜덤턴'></td>
</tr>
<tr> <tr>
<td align=center>명령 설정</td> <td align=center>명령 설정</td>
<td><input type=submit name=btn value='하야입력'><input type=submit name=btn value='방랑해산'></td> <td><input type=submit name=btn value='하야입력'><input type=submit name=btn value='방랑해산'></td>
+21 -150
View File
@@ -2,6 +2,8 @@
namespace sammo; namespace sammo;
use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -31,18 +33,18 @@ $src = MessageTarget::buildQuick($session->generalID);
$genObjList = []; $genObjList = [];
$env = []; $env = [];
if ($genlist) { if ($genlist) {
$genObjList = General::createGeneralObjListFromDB($genlist); $genObjList = General::createObjListFromDB($genlist);
$env = $gameStor->cacheAll(); $env = $gameStor->cacheAll();
} }
switch ($btn) { switch ($btn) {
case "전체 접속허용": case "전체 접속허용":
$db->update('general', [ $db->update('general_access_log', [
'con' => 0 'refresh_score' => 0
], true); ], true);
break; break;
case "전체 접속제한": case "전체 접속제한":
$db->update('general', [ $db->update('general_access_log', [
'con' => 1000 'refresh_score' => 1000
], true); ], true);
break; break;
case "블럭 해제": case "블럭 해제":
@@ -107,33 +109,11 @@ switch ($btn) {
'arg' => '{}', 'arg' => '{}',
'brief' => '휴식', 'brief' => '휴식',
], 'general_id IN %li AND turn_idx = 0', $genlist); ], 'general_id IN %li AND turn_idx = 0', $genlist);
break;
case "특기 부여":
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$text = "특기 부여!";
foreach ($db->query("SELECT `no`,leadership,strength,intel,dex1,dex2,dex3,dex4,dex5 FROM general WHERE `no` IN %li", $genlist) as $general) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($general['no']), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true);
$specialWar = SpecialityHelper::pickSpecialWar($general);
$db->update('general', [
'specage2' => $db->sqleval('age'),
'special2' => $specialWar
], 'no=%i', $general['no']);
$specialWarName = buildGeneralSpecialWarClass($specialWar)->getName();
$josaUl = JosaUtil::pick($specialWarName, '을');
$logger = new ActionLogger($general['no'], 0, $year, $month);
$logger->pushGeneralHistoryLog("특기 【<b><C>{$specialWarName}</></b>】{$josaUl} 습득");
$logger->pushGeneralActionLog("특기 【<b><L>{$specialWarName}</></b>】{$josaUl} 익혔습니다!",ActionLogger::PLAIN);
$logger->flush();
}
break; break;
case "경험치1000": case "경험치1000":
$text = $btn . " 지급!"; $text = $btn . " 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -144,7 +124,7 @@ switch ($btn) {
case "공헌치1000": case "공헌치1000":
$text = $btn . " 지급!"; $text = $btn . " 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -155,7 +135,7 @@ switch ($btn) {
case "보숙10000": case "보숙10000":
$text = "보병숙련도+10000 지급!"; $text = "보병숙련도+10000 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -165,7 +145,7 @@ switch ($btn) {
case "궁숙10000": case "궁숙10000":
$text = "궁병숙련도+10000 지급!"; $text = "궁병숙련도+10000 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -176,7 +156,7 @@ switch ($btn) {
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
$text = "기병숙련도+10000 지급!"; $text = "기병숙련도+10000 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -187,7 +167,7 @@ switch ($btn) {
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
$text = "귀병숙련도+10000 지급!"; $text = "귀병숙련도+10000 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -198,7 +178,7 @@ switch ($btn) {
$src = MessageTarget::buildQuick($session->generalID); $src = MessageTarget::buildQuick($session->generalID);
$text = "차병숙련도+10000 지급!"; $text = "차병숙련도+10000 지급!";
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
$db->update('general', [ $db->update('general', [
@@ -206,111 +186,22 @@ switch ($btn) {
], '`no` IN %li', $genlist); ], '`no` IN %li', $genlist);
break; break;
case "접속 허용": case "접속 허용":
$db->update('general', [ $db->update('general_access_log', [
'con' => 0 'refresh_score' => 0
], '`no` IN %li', $genlist); ], '`general_id` IN %li', $genlist);
break; break;
case "접속 제한": case "접속 제한":
$db->update('general', [ $db->update('general_access_log', [
'con' => 1000 'refresh_score' => 1000
], '`no` IN %li', $genlist); ], '`general_id` IN %li', $genlist);
break; break;
case "메세지 전달": case "메세지 전달":
$text = $msg ?? ''; $text = $msg ?? '';
foreach ($genlist as $generalID) { foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []); $msg = new Message(MessageType::private, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true); $msg->send(true);
} }
break; break;
case "무기지급":
if ($item == 'None') {
$text = "무기 회수!";
} else {
$text = getItemName($item) . " 지급!";
}
foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true);
}
if ($item === 'None') {
$db->update('general', [
'weapon' => 'None'
], '`no` IN %li', $genlist);
} else {
$db->update('general', [
'weapon' => $item
], '`no` IN %li', $genlist, $item);
}
break;
case "책지급":
if ($item == 'None') {
$text = "책 회수!";
} else {
$text = getItemName($item) . " 지급!";
}
foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true);
}
if ($item == 'None') {
$db->update('general', [
'book' => 'None'
], '`no` IN %li', $genlist);
} else {
$db->update('general', [
'book' => $item
], '`no` IN %li', $genlist);
}
break;
case "말지급":
if ($item == 'None') {
$text = "말 회수!";
} else {
$text = getItemName($item) . " 지급!";
}
foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true);
}
if ($item == 'None') {
$db->update('general', [
'horse' => 'None'
], '`no` IN %li', $genlist);
} else {
$db->update('general', [
'horse' => $item
], '`no` IN %li', $genlist);
}
break;
case "도구지급":
if ($item == 'None') {
$text = "특수도구 회수!";
} else {
$text = getItemName($item) . " 지급!";
}
foreach ($genlist as $generalID) {
$msg = new Message(Message::MSGTYPE_PRIVATE, $src, MessageTarget::buildQuick($generalID), $text, new \DateTime(), new \DateTime('9999-12-31'), []);
$msg->send(true);
}
if ($item == 'None') {
$db->update('general', [
'item' => 'None'
], '`no` IN %li', $genlist);
} else {
$db->update('general', [
'item' => $item
], '`no` IN %li AND item < %i', $genlist, $item);
}
break;
case "하야입력": case "하야입력":
$db->update('general_turn', [ $db->update('general_turn', [
'action' => 'che_하야', 'action' => 'che_하야',
@@ -330,26 +221,6 @@ switch ($btn) {
'brief' => '해산', 'brief' => '해산',
], 'general_id IN %li AND turn_idx = 1', $genlist); ], 'general_id IN %li AND turn_idx = 1', $genlist);
break; break;
case "00턴":
$turnterm = $gameStor->turnterm;
foreach ($genlist as $generalID) {
$turntime = getRandTurn($turnterm);
$cutTurn = cutTurn($turntime, $turnterm);
$db->update('general', [
'turntime' => $cutTurn
], '`no` IN %li', $genlist);
}
break;
case "랜덤턴":
$turnterm = $gameStor->turnterm;
foreach ($genlist as $generalID) {
$turntime = getRandTurn($turnterm);
$db->update('general', [
'turntime' => $turntime
], '`no` IN %li', $genlist);
}
break;
} }
header('location:_admin2.php'); header('location:_admin2.php');
-135
View File
@@ -1,135 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) {
die(requireAdminPermissionHTML());
}
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$conlimit = $gameStor->conlimit;
$ipGroupList = Util::arrayGroupBy(
$db->query(
'SELECT name,ip,lastconnect,owner,block,substring_index(ip,".",3) as ip_c from general WHERE ip!="" and npc<2'
),
'ip_c'
);
function colorBlockedName($general)
{
if (!$general['blocked']) {
return $general['name'];
}
return "<span style='color:magenta;'>{$general['name']}</span>";
}
?>
<!DOCTYPE html>
<html>
<head>
<title>멀티관리</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('ts', 'common', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>멀 티 관 리<br><?= backButton() ?></td>
</tr>
</table>
<form name=form1 method=post action=_admin4_submit.php>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td width=80 align=center rowspan=3>회원선택<br><br>
<font color=cyan>NPC</font><br>
<font color=skyblue>NPC유저</font><br>
<font color=red>접속제한</font><br><b style=background-color:red;>블럭회원</b>
</td>
<td width=105 rowspan=3>
<?php
echo "
<select name=genlist[] size=20 multiple style='color:white;background-color:black;font-size:14px'>";
foreach ($db->query('SELECT no,name,npc,block,con from general where ip!=\'\' order by npc,ip') as $general) {
$style = "style=;";
if ($general['block'] > 0) {
$style .= "background-color:red;";
}
if ($general['npc'] >= 2) {
$style .= "color:cyan;";
} elseif ($general['npc'] == 1) {
$style .= "color:skyblue;";
}
if ($general['con'] > $conlimit) {
$style .= "color:red;";
}
echo "
<option value={$general['no']} $style>{$general['name']}</option>";
}
echo "
</select>";
?>
</td>
<td width=100 align=center>블럭</td>
<td width=504>
<input type=submit name=btn value='블럭 해제'><input type=submit name=btn value='1단계 블럭'><input type=submit name=btn value='2단계 블럭'><input type=submit name=btn value='3단계 블럭'><input type=submit name=btn value='무한삭턴'><br>
1단계:발언권, 2단계:턴블럭
</td>
</tr>
<tr>
<td align=center>강제 사망</td>
<td><input type=submit name=btn value='강제 사망'></td>
</tr>
<tr>
<td align=center>메세지 전달</td>
<td><input type=textarea size=60 maxlength=255 name=msg style=background-color:black;color:white;><input type=submit name=btn value='메세지 전달'></td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td align=center width=100>장수명</td>
<td align=center width=180>최근로그인</td>
<td align=center width=129>IP</td>
<td align=center width=100>ID</td>
</tr>
<?php foreach ($ipGroupList as $ipGroupC => $users) : ?>
<tr>
<td><?= join('<br>', array_map('\sammo\colorBlockedName', $users)) ?></td>
<td><?= join('<br>', array_column($users, 'lastconnect')) ?></td>
<td><?= join('<br>', array_column($users, 'ip')) ?></td>
<td><?= join('<br>', array_column($users, 'owner')) ?></td>
</tr>
<?php endforeach; ?>
</table>
<?php
//NOTE: password의 md5 해시가 같은지 확인하는 방식으로는 앞으로 잡아낼 수 없다. 폐기
?>
</form>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
-84
View File
@@ -1,84 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
if ($session->userGrade < 5) {
header('location:_admin4.php');
die();
}
$btn = Util::getPost('btn');
$genlist = Util::getPost('genlist', 'array_int');
$msg = Util::getPost('msg', 'string', '메시지');
$db = DB::db();
//NOTE: 왜 기능이 admin2와 admin4가 같이 있는가?
//NOTE: 왜 블럭 시 admin4에선 금쌀을 없애지 않는가?
switch ($btn) {
case "블럭 해제":
DB::db()->query('update general set block=0 where no IN %li', $genlist);
break;
case "1단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=1,killturn=24 where no IN %li', $genlist);
//FIXME: subquery로 하는게 더 빠를 듯.
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "2단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=2,killturn=24 where no IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "3단계 블럭":
$date = TimeUtil::now();
$db = DB::db();
$db->query('update general set block=3,killturn=24 where no IN %li', $genlist);
$uid = $db->queryFirstColumn('select owner from general where no IN %li', $genlist);
RootDB::db()->query('update member set block_num=block_num+1,block_date=%s where id IN %ls', $date, $uid);
break;
case "무한삭턴":
DB::db()->query('update general set killturn=8000 where no IN %li', $genlist);
break;
case "강제 사망":
$date = TimeUtil::now(true);
$db->update('general', [
'killturn' => 0,
'turntime' => $date,
], '`no` IN %li', $genlist);
$db->update('general_turn', [
'action' => '휴식',
'arg' => '{}',
'brief' => '휴식'
], 'general_id IN %li AND turn_idx = 0', $genlist);
break;
case "메세지 전달":
$date = TimeUtil::now();
$src = MessageTarget::buildQuick($session->generalID);
foreach($genlist as $generalID){
$msgObj = new Message(
Message::MSGTYPE_PRIVATE,
$src,
MessageTarget::buildQuick($generalID),
$msg,
new \DateTime(),
new \DateTime('9999-12-31'),
[]
);
if ($msgObj) {
$msgObj->send(true);
}
}
break;
}
header('location:_admin4.php');
+3 -14
View File
@@ -5,7 +5,9 @@ namespace sammo;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
/** @var int */
$type = Util::getPost('type', 'int', 0); $type = Util::getPost('type', 'int', 0);
/** @var int */
$type2 = Util::getPost('type2', 'int', 0); $type2 = Util::getPost('type2', 'int', 0);
if ($type < 0 || $type > 17) { if ($type < 0 || $type > 17) {
@@ -36,6 +38,7 @@ $sel2[$type2] = "selected";
<head> <head>
<title>일제정보</title> <title>일제정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -63,8 +66,6 @@ $sel2[$type2] = "selected";
<option <?= $sel[8] ?? '' ?> value=8>평무</option> <option <?= $sel[8] ?? '' ?> value=8>평무</option>
<option <?= $sel[9] ?? '' ?> value=9>평지</option> <option <?= $sel[9] ?? '' ?> value=9>평지</option>
<option <?= $sel[10] ?? '' ?> value=10>평Lv</option> <option <?= $sel[10] ?? '' ?> value=10>평Lv</option>
<option <?= $sel[11] ?? '' ?> value=11>접속률</option>
<option <?= $sel[12] ?? '' ?> value=12>단기접</option>
<option <?= $sel[13] ?? '' ?> value=13>보숙</option> <option <?= $sel[13] ?? '' ?> value=13>보숙</option>
<option <?= $sel[14] ?? '' ?> value=14>궁숙</option> <option <?= $sel[14] ?? '' ?> value=14>궁숙</option>
<option <?= $sel[15] ?? '' ?> value=15>기숙</option> <option <?= $sel[15] ?? '' ?> value=15>기숙</option>
@@ -102,8 +103,6 @@ $sel2[$type2] = "selected";
<table align=center width=1600 class="tb_layout bg0"> <table align=center width=1600 class="tb_layout bg0">
<tr class='bg1'> <tr class='bg1'>
<td align=center>국명</td> <td align=center>국명</td>
<td align=center>접률</td>
<td align=center>단접</td>
<td align=center>국력</td> <td align=center>국력</td>
<td align=center>장수</td> <td align=center>장수</td>
<td align=center>속령</td> <td align=center>속령</td>
@@ -144,8 +143,6 @@ SELECT
A.gold, A.gold,
A.rice, A.rice,
COUNT(B.nation) AS gennum, COUNT(B.nation) AS gennum,
ROUND(AVG(B.connect), 1) AS connect,
ROUND(AVG(B.con), 1) AS con,
ROUND(AVG(B.dex1)) AS dex1, ROUND(AVG(B.dex1)) AS dex1,
ROUND(AVG(B.dex2)) AS dex2, ROUND(AVG(B.dex2)) AS dex2,
ROUND(AVG(B.dex3)) AS dex3, ROUND(AVG(B.dex3)) AS dex3,
@@ -190,12 +187,6 @@ GROUP BY B.nation
case 10: case 10:
$query .= " order by avg(B.explevel) desc"; $query .= " order by avg(B.explevel) desc";
break; break;
case 11:
$query .= " order by avg(B.connect) desc";
break;
case 12:
$query .= " order by avg(B.con) desc";
break;
case 13: case 13:
$query .= " order by avg(B.dex1) desc"; $query .= " order by avg(B.dex1) desc";
break; break;
@@ -237,8 +228,6 @@ from city where nation=%i', $nation['nation']);
echo " echo "
<tr> <tr>
<td align=center style=background-color:{$nation['color']};color:" . newColor($nation['color']) . ";>{$nation['name']}</td> <td align=center style=background-color:{$nation['color']};color:" . newColor($nation['color']) . ";>{$nation['name']}</td>
<td align=center>&nbsp;{$nation['connect']}&nbsp;</td>
<td align=center>&nbsp;{$nation['con']}&nbsp;</td>
<td align=center>&nbsp;{$nation['power']}&nbsp;</td> <td align=center>&nbsp;{$nation['power']}&nbsp;</td>
<td align=center>&nbsp;{$gen['cnt']}&nbsp;</td> <td align=center>&nbsp;{$gen['cnt']}&nbsp;</td>
<td align=center>&nbsp;{$city['cnt']}&nbsp;</td> <td align=center>&nbsp;{$city['cnt']}&nbsp;</td>
+4 -1
View File
@@ -2,6 +2,8 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralQueryMode;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -74,7 +76,7 @@ if (!$gen) {
$gen = $generalBasicList[0]['no']; $gen = $generalBasicList[0]['no'];
} }
$generalObj = General::createGeneralObjFromDB($gen); $generalObj = General::createObjFromDB($gen, null, GeneralQueryMode::FullWithAccessLog);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
@@ -83,6 +85,7 @@ $generalObj = General::createGeneralObjFromDB($gen);
<head> <head>
<title>로그정보</title> <title>로그정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
+3
View File
@@ -30,6 +30,7 @@ $sel[$type] = "selected";
<head> <head>
<title>외교정보</title> <title>외교정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -95,6 +96,8 @@ $sel[$type] = "selected";
case 7: case 7:
$state = "<font color=green>불가침</font>"; $state = "<font color=green>불가침</font>";
break; break;
default:
throw new \Exception("알 수 없는 외교 상태: {$dip['state']}");
} }
$date = TimeUtil::now(); $date = TimeUtil::now();
+4 -4
View File
@@ -25,8 +25,8 @@ foreach ($db->queryFirstColumn(
CheckHall($generalNo); CheckHall($generalNo);
} }
foreach(General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj){ $inheritPointManager = InheritancePointManager::getInstance();
$genObj->mergeTotalInheritancePoint(true); foreach(General::createObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc = 0')) as $genObj){
applyInheritanceUser($genObj->getVar('owner')); $inheritPointManager->mergeTotalInheritancePoint($genObj);
$genObj->clearInheritancePoint(); $inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
} }
+77 -30
View File
@@ -2,6 +2,10 @@
namespace sammo; namespace sammo;
use Ds\Set;
use sammo\Enums\RankColumn;
use sammo\Enums\AuctionType;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -17,39 +21,36 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("명장일람", 1); increaseRefresh("명장일람", 1);
$templates = new \League\Plates\Engine(__DIR__ . '/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1136" /> <meta name="viewport" content="width=500" />
<title><?= UniqueConst::$serverName ?>: 명장일람</title> <title><?= UniqueConst::$serverName ?>: 명장일람</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/hallOfFame.css') ?>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('ts', 'common') ?> <?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'bestGeneral']) ?>
</head> </head>
<body> <body>
<table align=center width=1100 class='tb_layout bg0'> <div id="container" class="bg0">
<tr> <div class="row gx-0">
<td>명 장 일 람<br><?= closeButton() ?></td> <div class="col">명 장 일 람<br><?= closeButton() ?></div>
</tr> </div>
</table> <div class="row gx-0">
<table align=center width=1100 class='tb_layout bg0'> <div class="col center">
<form name=form1 action=a_bestGeneral.php method=post> <form name=form1 action=a_bestGeneral.php method=get><input type=submit name=btn value='유저 보기'>
<tr>
<td align=center>
<input type=submit name=btn value='유저 보기'>
<input type=submit name=btn value='NPC 보기'> <input type=submit name=btn value='NPC 보기'>
</td> </form>
</tr> </div>
</form> </div>
</table>
<div style="margin:auto;width:1100px;">
<?php <?php
$ownerNameList = []; $ownerNameList = [];
@@ -209,6 +210,32 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
} }
return $v; return $v;
}], }],
["유 산 소 모 량", "int", function ($v) use ($gameStor) {
$v['value'] = $v[RankColumn::inherit_point_spent->value];
if ($gameStor->isunited) {
return $v;
}
$v['nationName'] = '???';
$v['pictureFullPath'] = GetImageURL(0) . "/default.jpg";
$v['name'] = '???';
$v['ownerName'] = null;
$v['bgColor'] = GameConst::$basecolor4;
$v['fgColor'] = newColor($v['bgColor']);
return $v;
}],
["유 산 획 득 량", "int", function ($v) use ($gameStor) {
$v['value'] = $v[RankColumn::inherit_point_earned->value];
if ($gameStor->isunited) {
return $v;
}
$v['nationName'] = '???';
$v['pictureFullPath'] = GetImageURL(0) . "/default.jpg";
$v['name'] = '???';
$v['ownerName'] = null;
$v['bgColor'] = GameConst::$basecolor4;
$v['fgColor'] = newColor($v['bgColor']);
return $v;
}],
]; ];
$generals = []; $generals = [];
@@ -274,10 +301,6 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
'generals' => array_slice($typeGenerals, 0, min(10, $validCnt)) 'generals' => array_slice($typeGenerals, 0, min(10, $validCnt))
]); ]);
} }
?>
</div>
<div style="margin:auto;width:1100px;margin-top:5px;">
<?php
//유니크 아이템 소유자 //유니크 아이템 소유자
$itemTypes = [ $itemTypes = [
'horse' => '명 마', 'horse' => '명 마',
@@ -308,6 +331,32 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
} }
} }
$dummyAuctionGeneral = [
'nation' => 0,
'no' => 0,
'ownerName' => '',
'pictureFullPath' => GetImageURL(0) . "/default.jpg",
'name' => '경매중',
'bgColor' => '#00582c',
'fgColor' => 'white',
'nationName' => '-',
];
foreach ($db->queryFirstColumn(
'SELECT `target` FROM ng_auction WHERE `finished` = 0 AND `type` = %s',
AuctionType::UniqueItem->value
) as $itemClassName) {
if(key_exists($itemClassName, $itemOwners)) {
$itemOwners[$itemClassName][] = $dummyAuctionGeneral;
}
else{
$itemOwners[$itemClassName] = [$dummyAuctionGeneral];
}
}
foreach (GameConst::$allItems as $itemType => $itemList) { foreach (GameConst::$allItems as $itemType => $itemList) {
$itemNameType = $itemTypes[$itemType]; $itemNameType = $itemTypes[$itemType];
$itemList = array_reverse($itemList, true); $itemList = array_reverse($itemList, true);
@@ -369,15 +418,13 @@ $templates = new \League\Plates\Engine(__DIR__ . '/templates');
]); ]);
} }
?> ?>
<div class="row gx-0">
<div class="col"><?= closeButton() ?></div>
</div>
<div class="row bg0 gx-0">
<div class="col bg0"><?= banner() ?></div>
</div>
</div> </div>
<table align=center width=1100 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html> </html>
+4 -2
View File
@@ -14,12 +14,14 @@ increaseRefresh("왕조일람", 1);
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 왕조일람</title> <title><?= UniqueConst::$serverName ?>: 왕조일람</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', 'common') ?> <?= WebUtil::printDist('ts', 'common') ?>
</head> </head>
@@ -55,7 +57,7 @@ increaseRefresh("왕조일람", 1);
<tr> <tr>
<td style="background-color:#333333;" align=center colspan=8> <td style="background-color:#333333;" align=center colspan=8>
<font size=5>현재 (<?= $year ?>年 <?= $month ?>月)</font> <font size=5>현재 (<?= $year ?>年 <?= $month ?>月)</font>
<a href="a_history.php"><button type='button'>역사 보기</button></a> <a href="v_history.php"><button type='button'>역사 보기</button></a>
</td> </td>
</tr> </tr>
</table> </table>
@@ -75,7 +77,7 @@ increaseRefresh("왕조일람", 1);
<a href="a_emperior_detail.php?select=<?= $emperior['no'] ?>"><button type='button'>자세히</button></a> <a href="a_emperior_detail.php?select=<?= $emperior['no'] ?>"><button type='button'>자세히</button></a>
<?php if ($emperior['server_id']) : ?> <?php if ($emperior['server_id']) : ?>
<a href="a_history.php?serverID=<?= $emperior['server_id'] ?>"><button type='button'>역사 보기</button></a> <a href="v_history.php?serverID=<?= $emperior['server_id'] ?>"><button type='button'>역사 보기</button></a>
<?php endif ?> <?php endif ?>
</td> </td>
</tr> </tr>
+5 -2
View File
@@ -24,10 +24,12 @@ $serverID = $emperior['server_id'] ?? ($emperior['serverID'] ?? null);
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 왕조일람</title> <title><?= UniqueConst::$serverName ?>: 왕조일람</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', 'common', true) ?> <?= WebUtil::printDist('ts', 'common', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
@@ -173,8 +175,9 @@ $serverID = $emperior['server_id'] ?? ($emperior['serverID'] ?? null);
if (!$nation['nation'] ?? null) { if (!$nation['nation'] ?? null) {
continue; continue;
} }
$nation += Json::decode($nation['data']); $nation = array_merge(Json::decode($nation['data']), $nation);
/** @var array $nation */
$nation['typeName'] = getNationType($nation['type']); $nation['typeName'] = getNationType($nation['type']);
$nation['levelName'] = getNationLevel($nation['level']); $nation['levelName'] = getNationLevel($nation['level']);
/** @var int[]|null $nationGenerals */ /** @var int[]|null $nationGenerals */
@@ -200,7 +203,7 @@ $serverID = $emperior['server_id'] ?? ($emperior['serverID'] ?? null);
} }
if (key_exists('aux', $nation) && !is_array($nation['aux'])) { if (key_exists('aux', $nation) && !is_array($nation['aux'])) {
$nation += Json::decode($nation['aux']); $nation = array_merge(Json::decode($nation['aux']), $nation);
} }
echo $templates->render('oldNation', $nation); echo $templates->render('oldNation', $nation);
+37 -21
View File
@@ -16,10 +16,13 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("장수일람", 2); increaseRefresh("장수일람", 2);
$me = $db->queryFirstRow('SELECT con,turntime FROM general WHERE owner = %i', $userID); $me = $db->queryFirstRow(
'SELECT refresh_score,turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner = %i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -29,10 +32,8 @@ if ($type <= 0 || $type > 15) {
} }
$ownerNameList = []; $ownerNameList = [];
if ($gameStor->isunited) { foreach (RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]) {
foreach (RootDB::db()->queryAllLists('SELECT no, name FROM member') as [$ownerID, $ownerName]) { $ownerNameList[$ownerID] = $ownerName;
$ownerNameList[$ownerID] = $ownerName;
}
} }
?> ?>
@@ -41,14 +42,25 @@ if ($gameStor->isunited) {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 장수일람</title> <title><?= UniqueConst::$serverName ?>: 장수일람</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', 'common') ?> <?= WebUtil::printDist('ts', 'common') ?>
<style>
.hidden {
display: none;
}
.generalName:hover > .hidden {
display: block;
}
</style>
</head> </head>
<body> <body>
@@ -100,7 +112,7 @@ if ($gameStor->isunited) {
6 => ['dedication', true], 6 => ['dedication', true],
7 => ['officer_level', true], 7 => ['officer_level', true],
8 => ['killturn', false], 8 => ['killturn', false],
9 => ['connect', true], 9 => ['refresh_score_total', true],
10 => ['experience', true], 10 => ['experience', true],
11 => ['personal', true], 11 => ['personal', true],
12 => ['special', true], 12 => ['special', true],
@@ -109,7 +121,12 @@ if ($gameStor->isunited) {
15 => ['npc', true], 15 => ['npc', true],
][$type]; ][$type];
$generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect from general order by %b %l', $orderKey, $orderDesc ? 'desc' : ''); $generalList = $db->query(
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total
FROM `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id order by %b %l',
$orderKey,
$orderDesc ? 'desc' : ''
);
echo " echo "
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
@@ -155,19 +172,17 @@ if ($gameStor->isunited) {
if ($general['npc'] >= 2) { $name = formatName($general['name'], $general['npc']);
$name = "<font color=cyan>{$general['name']}</font>";
} elseif ($general['npc'] == 1) {
$name = "<font color=skyblue>{$general['name']}</font>";
} else {
$name = "{$general['name']}";
}
if (key_exists($general['owner'], $ownerNameList)) { if (key_exists($general['owner'], $ownerNameList)) {
$name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>'; if ($gameStor->isunited) {
$name = $name . '<br><small class=\'userName\'>(' . $ownerNameList[$general['owner']] . ')</small>';
} else {
$name = $name . '<br><small class=\'userName hidden\'>(' . $ownerNameList[$general['owner']] . ')</small>';
}
} }
$general['connect'] = Util::round($general['connect'], -1); $general['refresh_score_total'] = Util::round($general['refresh_score_total'], -1);
$imageTemp = GetImageURL($general['imgsvr']); $imageTemp = GetImageURL($general['imgsvr']);
echo " echo "
@@ -178,9 +193,10 @@ if ($gameStor->isunited) {
data-general-strength='{$general['strength']}' data-general-strength='{$general['strength']}'
data-general-intel='{$general['intel']}' data-general-intel='{$general['intel']}'
data-is-npc='" . ($general['npc'] >= 2 ? 'true' : 'false') . "' data-is-npc='" . ($general['npc'] >= 2 ? 'true' : 'false') . "'
data-npc-type='{$general['npc']}'
> >
<td align=center><img class='generalIcon' width='64' height='64' src='{$imageTemp}/{$general['picture']}'></img></td> <td align=center><img class='generalIcon' width='64' height='64' src='{$imageTemp}/{$general['picture']}'></img></td>
<td align=center>$name</td> <td align=center class='generalName' onclick=''>$name</td>
<td align=center>{$general['age']}세</td> <td align=center>{$general['age']}세</td>
<td align=center>" . displayCharInfo($general['personal']) . "</td> <td align=center>" . displayCharInfo($general['personal']) . "</td>
<td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td> <td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td>
@@ -195,8 +211,8 @@ if ($gameStor->isunited) {
<td align=center>$strength</td> <td align=center>$strength</td>
<td align=center>$intel</td> <td align=center>$intel</td>
<td align=center>{$general['killturn']}</td> <td align=center>{$general['killturn']}</td>
<td align=center>{$general['connect']}"; <td align=center>" . $general['refresh_score_total'] ?? 0;
echo "<br>【" . getConnect($general['connect']) . "】</td> echo "<br>【" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . "】</td>
</tr>"; </tr>";
} }
echo " echo "
+22 -23
View File
@@ -43,23 +43,24 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1136" /> <meta name="viewport" content="width=500" />
<title><?= UniqueConst::$serverName ?>: 명예의 전당</title> <title><?= UniqueConst::$serverName ?>: 명예의 전당</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/hallOfFame.css') ?>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'hallOfFame']) ?> <?= WebUtil::printDist('ts', ['common', 'hallOfFame']) ?>
</head> </head>
<body> <body>
<table align=center width=1100 class='tb_layout bg0'> <div id="container" class="bg0">
<tr> <div class="row gx-0">
<td>명 예 의 전 당<br><?= closeButton() ?></td> <div class="col">명 예 의 전 당<br><?= closeButton() ?></div>
</tr> </div>
<tr> <div class="row gx-0">
<td> <div class="col center">
시나리오 검색 : <select id="by_scenario" name="by_scenario"> 시나리오 검색 : <select id="by_scenario" name="by_scenario">
<?php foreach ($scenarioList as $iterSeasonIdx => $subScenarioList) : ?> <?php foreach ($scenarioList as $iterSeasonIdx => $subScenarioList) : ?>
<option data-season="<?= $iterSeasonIdx ?>" value="" <?= ($iterSeasonIdx == $seasonIdx && $scenarioIdx === null) ? "selected='selected'" : '' ?>>* 시즌 : <?= $iterSeasonIdx ?> 종합 *</option> <option data-season="<?= $iterSeasonIdx ?>" value="" <?= ($iterSeasonIdx == $seasonIdx && $scenarioIdx === null) ? "selected='selected'" : '' ?>>* 시즌 : <?= $iterSeasonIdx ?> 종합 *</option>
@@ -69,10 +70,8 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
<?php endforeach; ?> <?php endforeach; ?>
?> ?>
</select> </select>
</td> </div>
</tr> </div>
</table>
<div style="margin:auto;width:1100px;">
<?php <?php
$types = [ $types = [
'experience' => ['명 성', 'int'], 'experience' => ['명 성', 'int'],
@@ -113,7 +112,8 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
$hallResult = array_map(function ($general) use ($typeValue, $ownerNameList) { $hallResult = array_map(function ($general) use ($typeValue, $ownerNameList) {
$aux = Json::decode($general['aux']); $aux = Json::decode($general['aux']);
$general += $aux; /** @var array $general */
$general = array_merge($aux, $general);
if (key_exists($general['owner'], $ownerNameList)) { if (key_exists($general['owner'], $ownerNameList)) {
$general['ownerName'] = $ownerNameList[$general['owner']]; $general['ownerName'] = $ownerNameList[$general['owner']];
@@ -121,10 +121,11 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
if (!key_exists('bgColor', $general)) { if (!key_exists('bgColor', $general)) {
if (!key_exists('color', $general)) { if (!key_exists('color', $general)) {
$general['bgColor'] = GameConst::$basecolor4; $color = GameConst::$basecolor4;
} else { } else {
$general['bgColor'] = $general['color']; $color = $general['color'];
} }
$general['bgColor'] = $color;
} }
if (!key_exists('fgColor', $general)) { if (!key_exists('fgColor', $general)) {
@@ -156,15 +157,13 @@ if ($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx] ?? [])) {
]); ]);
} }
?> ?>
<div class="row gx-0">
<div class="col"><?= closeButton() ?></div>
</div>
<div class="row bg0 gx-0">
<div class="col bg0"><?= banner() ?></div>
</div>
</div> </div>
<table align=center width=1100 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body> </body>
</html> </html>
-215
View File
@@ -1,215 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$btn = Util::getReq('btn');
$yearmonth = Util::getReq('yearmonth', 'int');
$serverID = Util::getReq('serverID', 'string', null);
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if (!$serverID) {
$serverID = UniqueConst::$serverID;
}
if ($serverID === UniqueConst::$serverID) {
increaseRefresh("연감", 1);
}
$admin = $gameStor->getValues(['startyear', 'year', 'month', 'map_theme']);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner = %i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
[$s_year, $s_month] = $db->queryFirstList('SELECT year, month FROM ng_history WHERE server_id = %s ORDER BY year ASC, month ASC LIMIT 1', $serverID);
$s = $s_year * 12 + $s_month;
if ($s_year === null) {
echo '인자 에러';
exit();
}
[$e_year, $e_month] = $db->queryFirstList('SELECT year, month FROM ng_history WHERE server_id = %s ORDER BY year DESC, month DESC LIMIT 1', $serverID);
$e = $e_year * 12 + $e_month;
if ($serverID !== UniqueConst::$serverID) {
$mapTheme = $db->queryFirstField('SELECT map FROM ng_games WHERE server_id=%s', $serverID) ?: 'che';
} else {
$mapTheme = $admin['map_theme'] ?? 'che';
}
//FIXME: $yearmonth가 올바르지 않을 경우에 처리가 필요.
if ($serverID !== UniqueConst::$serverID && !$yearmonth) {
$year = $s_year;
$month = $s_month;
} else if (!$yearmonth) {
$year = $admin['year'];
$month = $admin['month'] - 1;
} else {
$year = intdiv($yearmonth, 100);
$month = $yearmonth % 100;
if ($btn == "◀◀ 이전달") {
$month -= 1;
} elseif ($btn == "다음달 ▶▶") {
$month += 1;
}
}
$now = ($year * 12) + $month;
if ($now < $s) {
$now = $s;
}
if ($now > $e) {
$now = $e;
}
$year = intdiv($now, 12);
$month = $now % 12;
if ($month <= 0) {
$year -= 1;
$month += 12;
}
$history = $db->queryFirstRow('SELECT * FROM ng_history WHERE server_id = %s AND year = %i AND month = %i', $serverID, $year, $month);
$nations = Json::decode($history['nations']);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 연감</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS("js/map/theme_{$mapTheme}.js") ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/map.css') ?>
<?= WebUtil::printCSS('css/history.css') ?>
<?= WebUtil::printDist('ts', ['common', 'history']) ?>
<script>
var startYear = <?= $s_year ?>;
var startMonth = <?= $s_month ?>;
var lastYear = <?= $e_year ?>;
var lastMonth = <?= $e_month ?>;
var selectYear = <?= $year ?>;
var selectMonth = <?= $month ?>;
var nations = <?= $nations ? $history['nations'] : '{}' ?>;
</script>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>연 감<br><?= closeButton() ?></td>
</tr>
<tr>
<td>
<form name=form1 method=post>
연월 선택 :
<input type=submit name=btn value="◀◀ 이전달">
<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="다음달 ▶▶">
</form>
</td>
</tr>
</table>
<table align=center width=1000 height=520 class='tb_layout bg0'>
<thead>
<tr>
<th colspan=5 align=center class='bg1'>중 원 지 도</th>
</tr>
</thead>
<tbody>
<tr height=520>
<td width=698>
<?= getMapHtml($mapTheme) ?>
</td>
<td id='nation_list_frame'>
<table id='nation_list'>
<thead>
<tr>
<th width=130>국명</th>
<th width=70>국력</th>
<th width=45>장수</th>
<th width=45>속령</th>
</tr>
</thead>
<tbody>
<?php foreach ($nations as $nation) : ?>
<tr>
<td><span style='color:<?= newColor($nation['color']) ?>;background-color:<?= $nation['color'] ?>'><?= $nation['name'] ?></td>
<td style='text-align:right'><?= number_format($nation['power']) ?></td>
<td style='text-align:right'><?= number_format($nation['gennum']) ?></td>
<td style='text-align:right'><?= number_format(count($nation['cities'] ?? [])) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot></tfoot>
</table>
</td>
</tr>
<tr>
<th colspan=5 align=center class='bg1'>중 원 정 세</th>
</tr>
<tr>
<td colspan=5 valign=top>
<?= formatHistoryToHTML(Json::decode($history['global_history'])) ?>
</td>
</tr>
<tr>
<th colspan=5 align=center class='bg1'>장 수 동 향</th>
</tr>
<tr>
<td colspan=5 valign=top>
<?= formatHistoryToHTML(Json::decode($history['global_action'])) ?>
</td>
</tr>
</tbody>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
<script>
window.serverNick = '<?= DB::prefix() ?>';
window.serverID = '<?= UniqueConst::$serverID ?>';
reloadWorldMap({
targetJson: 'j_map_history.php?year=<?= $year ?>&month=<?= $month ?>&serverID=<?= $serverID ?>',
showMe: false,
neutralView: true,
useCachedMap: false,
year: <?= $year ?>,
month: <?= $month ?>,
});
</script>
</body>
</html>
+13 -13
View File
@@ -10,13 +10,16 @@ $userID = Session::getUserID();
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->cacheValues(['killturn', 'autorun_user', 'turnterm']);
increaseRefresh("세력일람", 2); increaseRefresh("세력일람", 2);
$me = $db->queryFirstRow('SELECT con, turntime FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT refresh_score, turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -26,13 +29,16 @@ if ($con >= 2) {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 세력일람</title> <title><?= UniqueConst::$serverName ?>: 세력일람</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'extKingdoms']) ?> <?= WebUtil::printDist('ts', ['common', 'extKingdoms']) ?>
<?= WebUtil::printStaticValues($gameStor->getValues(['killturn', 'autorun_user', 'turnterm'])) ?>
</head> </head>
<body> <body>
@@ -110,7 +116,7 @@ if ($con >= 2) {
} }
$chief = $chiefs[$chiefLevel] ?? ['name' => '-', 'npc' => 0]; $chief = $chiefs[$chiefLevel] ?? ['name' => '-', 'npc' => 0];
$officerLevelText = getOfficerLevelText($chiefLevel, $nation['level']); $officerLevelText = getOfficerLevelText($chiefLevel, $nation['level']);
$chiefText = getColoredName($chief['name'], $chief['npc']); $chiefText = formatName($chief['name'], $chief['npc']);
echo "<td class='center bg1'>{$officerLevelText}</td> echo "<td class='center bg1'>{$officerLevelText}</td>
<td class='center'>{$chiefText}</td>"; <td class='center'>{$chiefText}</td>";
} }
@@ -144,13 +150,7 @@ if ($con >= 2) {
<tr> <tr>
<td colspan=8> 장수 일람 : "; <td colspan=8> 장수 일람 : ";
foreach ($generals as $general) { foreach ($generals as $general) {
if ($general['npc'] >= 2) { echo formatName($general['name'], $general['npc']).', ';
echo "<font color=cyan>{$general['name']}</font>, ";
} elseif ($general['npc'] == 1) {
echo "<font color=skyblue>{$general['name']}</font>, ";
} else {
echo "{$general['name']}, ";
}
} }
echo " echo "
</td> </td>
@@ -183,7 +183,7 @@ if ($con >= 2) {
<tr> <tr>
<td colspan=5> 장수 일람 : "; <td colspan=5> 장수 일람 : ";
foreach ($nations[0]['generals'] as $general) { foreach ($nations[0]['generals'] as $general) {
$generalText = getColoredName($general['name'], $general['npc']); $generalText = formatName($general['name'], $general['npc']);
echo "{$generalText}, "; echo "{$generalText}, ";
} }
echo " echo "
+3 -1
View File
@@ -24,12 +24,14 @@ $sel[$type] = "selected";
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 빙의일람</title> <title><?= UniqueConst::$serverName ?>: 빙의일람</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common']) ?> <?= WebUtil::printDist('ts', ['common']) ?>
</head> </head>
@@ -111,7 +113,7 @@ $sel[$type] = "selected";
</tr> </tr>
<?php foreach ($generalList as $general) : ?> <?php foreach ($generalList as $general) : ?>
<tr> <tr>
<td align=center><?= getColoredName($general['name'], $general['npc']) ?></td> <td align=center><?= formatName($general['name'], $general['npc']) ?></td>
<td align=center><?= $general['owner_name'] ?></td> <td align=center><?= $general['owner_name'] ?></td>
<td align=center>Lv <?= $general['explevel'] ?></td> <td align=center>Lv <?= $general['explevel'] ?></td>
<td align=center><?= $nationName[$general['nation']] ?></td> <td align=center><?= $nationName[$general['nation']] ?></td>
-88
View File
@@ -1,88 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("세력도", 2);
TurnExecutionHelper::executeAllCommand();
$mapTheme = $gameStor->map_theme ?? 'che';
$me = $db->queryFirstRow('SELECT con,turntime from general where owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 세력도</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printCSS('css/normalize.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/map.css') ?>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS('d_shared/base_map.js') ?>
<?= WebUtil::printDist('ts', ['common', 'map']) ?>
<script>
window.serverNick = '<?= DB::prefix() ?>';
window.serverID = '<?= UniqueConst::$serverID ?>';
$(function() {
reloadWorldMap({
neutralView: true,
showMe: true,
useCachedMap: true
});
});
</script>
</head>
<body>
<table align=center width=1200 class='tb_layout bg0'>
<tr>
<td>세 력 도<br><?= closeButton() ?></td>
</tr>
</table>
<table align=center width=1200 height=520 class='tb_layout bg0'>
<tr height=520>
<td width=498 valign=top>
<?= formatHistoryToHTML(getGlobalActionLogRecent(34)) ?>
</td>
<td width=698>
<?= getMapHtml($mapTheme) ?>
</td>
</tr>
<tr>
<td colspan=2 valign=top>
<?= formatHistoryToHTML(getGlobalHistoryLogRecent(34)) ?>
</td>
</tr>
</table>
<table align=center width=1200 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
+34 -34
View File
@@ -2,36 +2,29 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("갱신정보", 2); increaseRefresh("갱신정보", 1);
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxrefresh', 'maxonline']); $admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxrefresh', 'maxonline', 'recentTraffic']);
$log = getRawFileLogRecent(__DIR__ . '/logs/' . UniqueConst::$serverID . '/_traffic.txt', 11, 100); $recentTraffic = $admin['recentTraffic'] ?? [];
$date = [];
$year = [];
$month = [];
$refresh = [];
$online = [];
$curonline = getOnlineNum(); $curonline = getOnlineNum();
foreach ($log as $i => $value) {
$parse = Json::decode($value); $recentTraffic[] = [
$date[$i] = $parse[0]; 'year' => $admin['year'],
$year[$i] = $parse[1]; 'month' => $admin['month'],
$month[$i] = $parse[2]; 'refresh' => $admin['refresh'],
$refresh[$i] = $parse[3]; 'online' => $curonline,
$online[$i] = $parse[4]; 'date' => TimeUtil::now()
} ];
$year[] = $admin['year'];
$month[] = $admin['month'];
$date[] = TimeUtil::now();
if ($admin['maxrefresh'] == 0) { if ($admin['maxrefresh'] == 0) {
$admin['maxrefresh'] = 1; $admin['maxrefresh'] = 1;
@@ -52,6 +45,7 @@ if ($admin['maxonline'] < $curonline) {
<head> <head>
<title><?= UniqueConst::$serverName ?>: 트래픽정보</title> <title><?= UniqueConst::$serverName ?>: 트래픽정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -83,6 +77,7 @@ if ($admin['maxonline'] < $curonline) {
} }
</style> </style>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common']) ?> <?= WebUtil::printDist('ts', ['common']) ?>
</head> </head>
@@ -103,13 +98,13 @@ if ($admin['maxonline'] < $curonline) {
</td> </td>
</tr> </tr>
<?php <?php
$refresh[] = $admin['refresh']; foreach ($recentTraffic as $trafficItem) {
foreach ($refresh as $i => $value) { $value = $trafficItem['refresh'];
$w = round($value / $admin['maxrefresh'] * 100, 1); $w = round($value / $admin['maxrefresh'] * 100, 1);
$color = getTrafficColor($w); $color = getTrafficColor($w);
$dt = substr($date[$i], 11, 5); ?> $dt = substr($trafficItem['date'], 11, 5); ?>
<tr height=30> <tr height=30>
<td width=100 align=center><?= $year[$i] ?>년 <?= $month[$i] ?>월</td> <td width=100 align=center><?= $trafficItem['year'] ?>년 <?= $trafficItem['month'] ?>월</td>
<td width=60 align=center class='bg2'><?= $dt ?></td> <td width=60 align=center class='bg2'><?= $dt ?></td>
<td width=2 align=center class='bg1'></td> <td width=2 align=center class='bg1'></td>
<td width=320> <td width=320>
@@ -144,13 +139,13 @@ if ($admin['maxonline'] < $curonline) {
</td> </td>
</tr> </tr>
<?php <?php
$online[] = $curonline; foreach ($recentTraffic as $trafficItem) {
foreach ($online as $i => $value) { $value = $trafficItem['online'];
$w = round($value / $admin['maxonline'] * 100, 1); $w = round($value / $admin['maxonline'] * 100, 1);
$color = getTrafficColor($w); $color = getTrafficColor($w);
$dt = substr($date[$i], 11, 5); ?> $dt = substr($trafficItem['date'], 11, 5); ?>
<tr height=30> <tr height=30>
<td width=100 align=center><?= $year[$i] ?>년 <?= $month[$i] ?>월</td> <td width=100 align=center><?= $trafficItem['year'] ?>년 <?= $trafficItem['month'] ?>월</td>
<td width=60 align=center class='bg2'><?= $dt ?></td> <td width=60 align=center class='bg2'><?= $dt ?></td>
<td width=2 align=center class='bg1'></td> <td width=2 align=center class='bg1'></td>
<td width=320> <td width=320>
@@ -185,19 +180,24 @@ if ($admin['maxonline'] < $curonline) {
</td> </td>
</tr> </tr>
<?php <?php
$max_refresh = $db->queryFirstRow('SELECT sum(refresh) as refresh, sum(`connect`) as `connect` from general'); $totalRefresh = [
$max_refresh['name'] = '접속자 총합'; ...$db->queryFirstRow('SELECT sum(`refresh`) as `refresh`, sum(`refresh_score_total`) as `refresh_score_total` from general_access_log'),
'name' => '접속자 총합'
];
$refresh_result = array_merge([$max_refresh], $db->query('SELECT `name`,refresh,`connect` FROM general ORDER BY refresh DESC LIMIT 5')); $top5Refresh = $db->query(
'SELECT `name`, `log`.`refresh`, `refresh_score_total` FROM `general_access_log` AS `log`
INNER JOIN `general` ON `log`.`general_id` = `general`.`no` ORDER BY `log`.`refresh` DESC LIMIT 5'
);
foreach ($refresh_result as $i => $user) { foreach (array_merge([$totalRefresh], $top5Refresh) as $i => $user) {
$w = round($user['refresh'] / max(1, $max_refresh['refresh']) * 100, 1); $w = round($user['refresh'] / max(1, $totalRefresh['refresh']) * 100, 1);
$w2 = round(100 - $w, 1); $w2 = round(100 - $w, 1);
$color = getTrafficColor($w); $color = getTrafficColor($w);
?> ?>
<tr> <tr>
<td width=98 align=center><?= $user['name'] ?></td> <td width=98 align=center><?= $user['name'] ?></td>
<td width=98 align=center><?= $user['connect'] ?>(<?= $user['refresh'] ?>)</td> <td width=98 align=center><?= $user['refresh_score_total'] ?>(<?= $user['refresh'] ?>)</td>
<td width=798> <td width=798>
<?php if ($w == 0) : ?> <?php if ($w == 0) : ?>
<?php elseif ($w < 10) : ?> <?php elseif ($w < 10) : ?>
-434
View File
@@ -1,434 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("설문조사", 1);
$isVoteAdmin = in_array('vote', $session->acl[DB::prefix()] ?? []);
$isVoteAdmin = $isVoteAdmin || $session->userGrade >= 5;
$me = $db->queryFirstRow('SELECT no,vote from general where owner=%i', $userID);
$admin = $gameStor->getValues(['develcost', 'voteopen', 'vote_title', 'vote', 'votecomment']);
$vote_title = $admin['vote_title'] ?? '-';
$vote = $admin['vote'] ?: ['-'];
?>
<!DOCTYPE html>
<html>
<head>
<title><?= UniqueConst::$serverName ?>: 설문조사</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<style>
.little_bar {
float: left;
position: relative;
height: 17px;
line-height: 17px;
text-align: center;
}
</style>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('ts', ['common']) ?>
<script type="text/javascript">
function captureKey(e) {
if (e.keyCode == 13 && e.srcElement.type == 'text') {
form1.btn.value = '댓글';
form1.btn.click();
return false;
}
}
</script>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>설 문 조 사<br><?= closeButton() ?></td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<form name=form1 action=c_vote.php method=post>
<tr>
<td colspan=3 align=center class='bg2'>
<font size=5>설 문 조 사 (<?= $admin['develcost'] * 5 ?>금과 추첨으로 유니크템 증정!)</font>
</td>
</tr>
<?php
if ($isVoteAdmin) {
echo "
<tr>
<td width=48 align=center><input type=submit name=btn value='알림'></td>
<td width=98 align=center><input type=submit name=btn value='수정'></td>
<td width=848 align=left><input type=text name=title style=width:848px;></td>
</tr>
";
}
$vote_title = Tag2Code($vote_title);
echo "
<tr>
<td colspan=2 width=148 align=center class='bg1'>제 목</td>
<td width=848 align=left>&nbsp;{$vote_title}</td>
</tr>
";
$voteCount = $db->queryFirstField('SELECT count(no) FROM general WHERE vote>0 AND npc<2');
$allCount = $db->queryFirstField('SELECT count(no) FROM general WHERE npc<2');
$percentage = round($voteCount / $allCount * 100, 1);
$voteTypeCount = count($vote);
for ($i = 1; $i < $voteTypeCount; $i++) {
echo "
<tr>
<td width=48 align=center style=color:" . getNewColor($i) . "; bgcolor=" . getVoteColor($i) . ">{$i}.</td>
<td width=98 align=center>
";
if ($me['vote'] == 0 && $me['no'] > 0) {
echo "
<input type=radio name=sel value={$i}>
";
} elseif ($admin['voteopen'] >= 1 || $isVoteAdmin) {
$vCount = $db->queryFirstField('SELECT count(no) FROM general WHERE vote=%i', $i);
$per = @round($vCount / $voteCount * 100, 1);
echo "{$vCount} 표 ({$per}%)";
} else {
echo "추후공개";
}
$vote[$i] = Tag2Code($vote[$i]);
echo "
</td>
<td align=left>&nbsp;{$vote[$i]}</td>
</tr>
";
}
echo "
<tr>
";
if ($me['vote'] == 0 && $me['no'] > 0) {
echo "
<td align=center>투표</td>
<td align=center><input type=submit name=btn value='투표'></td>
";
} else {
echo "
<td colspan=2 align=center>결산</td>
";
}
echo "
<td align=left>&nbsp;투표율 : {$voteCount} / {$allCount} ({$percentage} %)</td>
</tr>
";
if ($isVoteAdmin) {
echo "
<tr>
<td align=center><input type=submit name=btn value='리셋'></td>
<td align=center><input type=submit name=btn value='추가'></td>
<td align=left><input type=text name=str style=width:848px;></td>
</tr>
";
}
if ($admin['votecomment']) {
$comment = $admin['votecomment'];
$commentCount = count($comment);
} else {
$commentCount = 0;
}
echo "
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=4 align=center class='bg1'>댓 글</td>
</tr>
";
for ($i = 0; $i < $commentCount; $i++) {
$cmt = $comment[$i];
$cmt[2] = Tag2Code($cmt[2]);
$j = $i + 1;
echo "
<tr>
<td width=28 align=center>{$j}.</td>
<td width=130 align=center>{$cmt[0]}</td>
<td width=130 align=center>{$cmt[1]}</td>
<td width=712 align=left>&nbsp;{$cmt[2]}</td>
</tr>
";
}
if ($me['no'] > 0) {
echo "
<tr>
<td width=158 colspan=2 align=center>-</td>
<td width=130 align=center><input type=submit name=btn value='댓글'></td>
<td align=left><input type=text name=comment maxlength=60 style=width:700px; onkeydown='return captureKey(event)'></td>
</tr>
";
}
?>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=3 align=center class='bg2'>
<font size=5>
전 체 통 계
<?php
if ($isVoteAdmin) {
echo "
<input type=submit name=btn value='숨김'>
<input type=submit name=btn value='전체통계만'>
<input type=submit name=btn value='전부'>";
}
echo "
</font></td></tr>";
if ($admin['voteopen'] >= 1 || $isVoteAdmin) {
echo "
<tr>
<td width=130 align=center>전 체</td>
<td width=128 align=center>{$voteCount} / {$allCount} ({$percentage} %)</td>
<td width=742>
";
$memCount = max(1, $db->queryFirstField('SELECT count(`no`) FROM general WHERE npc<2'));
$totalVote = [];
$nationVoteCount = [];
$nationVote = [];
foreach ($db->query("SELECT nation, vote, count(`no`) as cnt FROM general WHERE npc<2 GROUP BY nation, vote") as $row) {
$nation = $row['nation'];
$ownVote = $row['vote'];
$cnt = $row['cnt'];
if (!isset($totalVote[$ownVote])) {
$totalVote[$ownVote] = 0;
}
if (!isset($nationVoteCount[$nation])) {
$nationVoteCount[$nation] = 0;
$nationVote[$nation] = [];
}
if (!isset($nationVote[$nation][$ownVote])) {
$nationVote[$nation][$ownVote] = 0;
}
$totalVote[$ownVote] += $cnt;
$nationVoteCount[$nation] += $cnt;
$nationVote[$nation][$ownVote] += $cnt;
}
$totalPer = 0;
for ($i = 0; $i < $voteTypeCount; $i++) {
$per = round(($totalVote[$i] ?? 0) * 100 / $memCount, 1);
if ($i == $voteTypeCount - 1) {
$per = 100 - $totalPer;
} else {
$totalPer += $per;
}
// if($per < 5) { $vote['cnt'] = "&nbsp;"; }
?>
<?php if ($per == 0) : ?>
<?php elseif ($per < 10) : ?>
<div class='little_bar' style='width:<?= $per ?>%;color:<?= getNewColor($i) ?>;background-color:<?= getVoteColor($i) ?>;'></div>
<?php else : ?>
<div class='little_bar' style='width:<?= $per ?>%;color:<?= getNewColor($i) ?>;background-color:<?= getVoteColor($i) ?>;'><?= $totalVote[$i] ?></div>
<?php endif; ?>
<?php
}
echo "
</td>
</tr>
";
}
if ($admin['voteopen'] >= 2 || $isVoteAdmin) {
$memCount = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=0 AND npc <2');
if ($memCount == 0) {
$memCount = 1;
}
if (!isset($nationVoteCount[0])) {
$nationVoteCount[0] = 0;
}
$percentage = round($nationVoteCount[0] / $memCount * 100, 1);
echo "
<tr>
<td align=center bgcolor=black>재 야</td>
<td align=center>{$nationVoteCount[0]} / {$memCount} ({$percentage} %)</td>
<td>
";
$totalPer = 0;
for ($i = 0; $i < $voteTypeCount; $i++) {
$per = round(Util::array_get($nationVote[0][$i], 0) / $memCount * 100, 1);
if ($i == $voteTypeCount - 1) {
$per = 100 - $totalPer;
} else {
$totalPer += $per;
}
// if($per < 5) { $vote['cnt'] = "&nbsp;"; }
?>
<?php if ($per == 0) : ?>
<?php elseif ($per < 10) : ?>
<div class='little_bar' style='width:<?= $per ?>%;color:<?= getNewColor($i) ?>;background-color:<?= getVoteColor($i) ?>;'></div>
<?php else : ?>
<div class='little_bar' style='width:<?= $per ?>%;color:<?= getNewColor($i) ?>;background-color:<?= getVoteColor($i) ?>;'><?= $nationVote[0][$i] ?></div>
<?php endif; ?>
<?php
}
echo "
</td>
</tr>
";
foreach ($db->query('SELECT nation,color,name,gennum from nation order by gennum desc') as $i => $nation) {
$memCount = $db->queryFirstField('SELECT count(no) FROM general WHERE nation=%i AND npc<2', $nation['nation']);
$voteCount = $nationVoteCount[$nation['nation']] ?? 0;
if ($memCount == 0) {
$percentage = 100;
} else {
$percentage = round($voteCount / $memCount * 100, 1);
}
echo "
<tr>
<td align=center style=color:" . newColor($nation['color']) . "; bgcolor={$nation['color']}>{$nation['name']}</td>
<td align=center>{$voteCount} / {$memCount} ({$percentage} %)</td>
<td align=center>
";
$totalPer = 0;
for ($k = 0; $k < $voteTypeCount; $k++) {
if ($memCount == 0) {
$per = 0;
continue;
}
$per = round(($nationVote[$nation['nation']][$k] ?? 0) / $memCount * 100, 1);
if ($i == $voteTypeCount - 1) {
$per = 100 - $totalPer;
} else {
$totalPer += $per;
}
// if($per < 5) { $vote['cnt'] = "&nbsp;"; }
?>
<?php if ($per == 0) : ?>
<?php elseif ($per < 10) : ?>
<div class='little_bar' style='width:<?= $per ?>%;color:<?= getNewColor($k) ?>;background-color:<?= getVoteColor($k) ?>;'></div>
<?php else : ?>
<div class='little_bar' style='width:<?= $per ?>%;color:<?= getNewColor($k) ?>;background-color:<?= getVoteColor($k) ?>;'><?= $nationVote[$nation['nation']][$k] ?? 0 ?></div>
<?php endif; ?>
<?php
}
echo "
</td>
</tr>
";
}
}
?>
</form>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
<?php
function getVoteColor($type)
{
if ($type > 0) {
$type = (($type - 1) % 7) + 1;
}
switch ($type) {
default:
case 0:
$color = "black";
break;
case 1:
$color = "red";
break;
case 2:
$color = "orange";
break;
case 3:
$color = "yellow";
break;
case 4:
$color = "green";
break;
case 5:
$color = "blue";
break;
case 6:
$color = "navy";
break;
case 7:
$color = "purple";
break;
}
return $color;
}
function getNewColor($type)
{
if ($type > 0) {
$type = (($type - 1) % 7) + 1;
}
switch ($type) {
case 2:
$color = "black";
break;
case 3:
$color = "black";
break;
default:
$color = "white";
break;
}
return $color;
}
+6 -1
View File
@@ -5,4 +5,9 @@ namespace sammo;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
APIHelper::launch(dirname(__FILE__)); $eParams = $_GET;
if(key_exists('path', $eParams)){
unset($eParams['path']);
}
APIHelper::launch(dirname(__FILE__), $_GET['path']??'', $eParams, true);
-306
View File
@@ -1,306 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$msg = Util::getReq('msg');
$msg2 = Util::getReq('msg2');
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("거래장", 2);
$me = $db->queryFirstRow('SELECT no,special,con,turntime from general where owner=%i', $userID);
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
$tradeCount = $db->queryFirstField('SELECT count(no) FROM auction WHERE no1=%i', $me['no']);
$bidCount = $db->queryFirstField('SELECT count(no) FROM auction where no2=%i', $me['no']);
$btCount = $tradeCount + $bidCount;
if ($session->userGrade >= 5 || $btCount < 1) {
$btn = "submit";
} else {
$btn = "hidden";
}
if ($msg == "") {
$msg = "-";
}
if ($msg2 == "") {
$msg2 = "-";
}
?>
<!DOCTYPE html>
<html>
<head>
<title><?= UniqueConst::$serverName ?>: 거래장</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('ts', ['common']) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>거 래 장<br><?= closeButton() ?></td>
</tr>
<tr>
<td align=center class='bg2'>
<font color=orange size=6><b>거 래 장</b></font><input type=button value='갱신' onclick="location.replace('b_auction.php')">
</td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<form method=post action=c_auction.php>
<tr>
<td colspan=11 align=center bgcolor=orange>
<font size=5>팝 니 다</font>
</td>
</tr>
<tr align=center class='bg1'>
<td width=68>거래번호</td>
<td width=48>선택</td>
<td width=98>판매자</td>
<td width=118>물품</td>
<td width=88>수량</td>
<td width=88>시작판매가</td>
<td width=88>현재판매가</td>
<td width=88>즉시판매가</td>
<td width=48>단가</td>
<td width=98>구매 예정자</td>
<td width=148>거래종료</td>
</tr>
<?php
$chk = 0;
foreach ($db->query('SELECT * from auction where type=0 order by expire') as $auction) {
$radio = "";
$alert = "";
$alert2 = "";
if ($auction['no1'] == $me['no']) {
$radio = " disabled";
} elseif ($auction['no2'] > 0 && $auction['amount'] * 2 <= $auction['value']) {
$radio = " disabled";
$alert = "<font color=red>";
$alert2 = "</font>";
} elseif ($auction['no2'] > 0 && $auction['topv'] <= $auction['value']) {
$radio = " disabled";
$alert = "<font color=red>";
$alert2 = "</font>";
} elseif ($chk == 0) {
$radio = " checked";
$chk = 1;
}
$pv = round($auction['value'] * 100 / $auction['amount']) / 100 + 0.001;
$pv = substr((string)$pv, 0, 4);
echo "
<tr align=center>
<td>{$auction['no']}</td>
<td><input type=radio name=sel value={$auction['no']}{$radio}></td>
<td>{$auction['name1']}</td>
<td>쌀</td>
<td>{$auction['amount']}</td>
<td>금 {$auction['cost']}</td>
<td>{$alert}금 {$auction['value']}{$alert2}</td>
<td>{$alert}금 {$auction['topv']}{$alert2}</td>
<td>{$alert}{$pv}{$alert2}</td>
<td>{$alert}{$auction['name2']}{$alert2}</td>
<td>{$auction['expire']}</td>
</tr>
";
}
?>
<tr height=25>
<td align=center class='bg1'>등록결과</td>
<td colspan=10><?= ConvertLog($msg) ?></td>
</tr>
<tr>
<td align=center class='bg1'>입찰등록</td>
<td colspan=10>
 지불할 금액: <input type=text style=color:white;background-color:black; size=6 maxlength=6 name=value>
<input type=<?= $btn ?> name=btn value='구매시도' onclick='return confirm("정말 입찰하시겠습니까?");'>
</td>
</tr>
<tr>
<td align=center class='bg1'>거래등록</td>
<td colspan=10>
 종료: <input type=text style=color:white;background-color:black; size=2 maxlength=2 name=term value=12>턴 후
 물품: 쌀
 판매량: <input type=text style=color:white;background-color:black; size=5 maxlength=5 name=amount value=1000>
 시작가: <input type=text style=color:white;background-color:black; size=5 maxlength=5 name=cost value=500>
 즉구가: <input type=text style=color:white;background-color:black; size=5 maxlength=5 name=topv value=2000>
<input type=<?= $btn ?> name=btn value='판매' onclick='return confirm("정말 판매하시겠습니까?");'>
</td>
</tr>
<tr>
<td colspan=11>
ㆍ<font color=cyan>Hint</font>) 거래자가 판매(물품 판매, 금 수령), 입찰자가 구매(물품 구입, 금 지불).<br>
ㆍ<font color=cyan>Hint</font>) 단가가 1.00보다 높을수록 판매자 유리.<br>
ㆍ<font color=cyan>Hint</font>) 단가가 1.00보다 낮을수록 입찰자 유리.<br>
</td>
</tr>
</form>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<form method=post action=c_auction.php>
<tr>
<td colspan=11 align=center bgcolor=skyblue>
<font size=5>삽 니 다</font>
</td>
</tr>
<tr align=center class='bg1'>
<td width=68>거래번호</td>
<td width=48>선택</td>
<td width=98>구매자</td>
<td width=118>물품</td>
<td width=88>수량</td>
<td width=88>시작구매가</td>
<td width=88>현재구매가</td>
<td width=88>즉시구매가</td>
<td width=48>단가</td>
<td width=98>판매 예정자</td>
<td width=148>거래종료</td>
</tr>
<?php
$chk = 0;
foreach ($db->query('SELECT * from auction where type=1 order by expire') as $auction) {
$radio = "";
$alert = "";
$alert2 = "";
if ($auction['no1'] == $me['no']) {
$radio = " disabled";
} elseif ($auction['no2'] > 0 && $auction['amount'] >= $auction['value'] * 2) {
$radio = " disabled";
$alert = "<font color=red>";
$alert2 = "</font>";
} elseif ($auction['no2'] > 0 && $auction['topv'] >= $auction['value']) {
$radio = " disabled";
$alert = "<font color=red>";
$alert2 = "</font>";
} elseif ($chk == 0) {
$radio = " checked";
$chk = 1;
}
$pv = round($auction['value'] * 100 / $auction['amount']) / 100 + 0.001;
$pv = substr((string)$pv, 0, 4);
echo "
<tr align=center>
<td>{$auction['no']}</td>
<td><input type=radio name=sel value={$auction['no']}{$radio}></td>
<td>{$auction['name1']}</td>
<td>쌀</td>
<td>{$auction['amount']}</td>
<td>금 {$auction['cost']}</td>
<td>{$alert}금 {$auction['value']}{$alert2}</td>
<td>{$alert}금 {$auction['topv']}{$alert2}</td>
<td>{$alert}{$pv}{$alert2}</td>
<td>{$alert}{$auction['name2']}{$alert2}</td>
<td>{$auction['expire']}</td>
</tr>
";
}
?>
<tr height=25>
<td align=center class='bg1'>등록결과</td>
<td colspan=10><?= ConvertLog($msg2) ?></td>
</tr>
<tr>
<td align=center class='bg1'>입찰등록</td>
<td colspan=10>
 수령할 금액: <input type=text style=color:white;background-color:black; size=6 maxlength=6 name=value>
<input type=<?= $btn ?> name=btn value='판매시도' onclick='return confirm("정말 입찰하시겠습니까?");'>
</td>
</tr>
<tr>
<td align=center class='bg1'>거래등록</td>
<td colspan=10>
 종료: <input type=text style=color:white;background-color:black; size=2 maxlength=2 name=term value=12>턴 후
 물품: 쌀
 구입량: <input type=text style=color:white;background-color:black; size=5 maxlength=5 name=amount value=1000>
 시작가: <input type=text style=color:white;background-color:black; size=5 maxlength=5 name=cost value=2000>
 즉구가: <input type=text style=color:white;background-color:black; size=5 maxlength=5 name=topv value=500>
<input type=<?= $btn ?> name=btn value='구매' onclick='return confirm("정말 구매하시겠습니까?");'>
</td>
</tr>
<tr>
<td colspan=11>
ㆍ<font color=cyan>Hint</font>) 거래자가 구매(물품 구매, 금 지불), 입찰자가 판매(물품 판매, 금 수령).<br>
ㆍ<font color=cyan>Hint</font>) 단가가 1.00보다 낮을수록 구매자 유리.<br>
ㆍ<font color=cyan>Hint</font>) 단가가 1.00보다 높을수록 입찰자 유리.<br>
</td>
</tr>
</form>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td align=center class='bg2'>
<font size=5>최 근 기 록</font>
</td>
</tr>
<tr>
<td>
<?= getAuctionLogRecent(20) ?>
</td>
</tr>
<tr>
<td align=center class='bg2'>
<font size=5>도 움 말</font>
</td>
</tr>
<tr>
<td>
<font color=white size=2>
ㆍ판매거래는 거래자가 판매할 물품을 거래하면, 구입을 희망하는 사람이 현재가보다 높게 입찰하여 구입하는 방식입니다.<br>
ㆍ<font color=cyan>Hint</font>) 쌀이 귀한 경우는 입찰자가 많아서 자연스레 단가가 오르게 됩니다. (해당 물품을 사려는 가격이 오름)<br>
ㆍ<font color=cyan>Hint</font>) 쌀이 흔한 경우는 초기 가격을 낮게 책정해야 판매가 가능할 겁니다.<br>
ㆍ구매거래는 거래자가 구입할 물품을 거래하면, 판매를 희망하는 사람이 현재가보다 낮게 입찰하여 판매하는 방식입니다.<br>
ㆍ<font color=cyan>Hint</font>) 쌀이 흔한 경우는 입찰자가 많아서 자연스레 단가가 내리게 됩니다. (해당 물품을 팔려는 가격이 내림)<br>
ㆍ<font color=cyan>Hint</font>) 쌀이 귀한 경우는 초기 가격을 높게 책정해야 구입이 가능할 겁니다.<br>
ㆍ마감임박때 입찰하는 경우 입찰후 1턴 후로 종료시간이 연장됩니다.<br>
ㆍ즉시구매가로 입찰하는 경우 입찰후 1턴 후로 종료시간이 결정됩니다.<br>
ㆍ악용 방지를 위해 50% ~ 200%의 가격에서 거래시작이 가능합니다.<br>
ㆍ악용 방지를 위해 즉시판매가는 110% 이상, 즉시구매가는 90% 이하의 시세로 가능합니다.<br>
ㆍ악용 방지를 위해 즉시판매가는 시작판매가의 110% 이상, 즉시구매가는 시작구매가의 90% 이하로 가능합니다.<br>
ㆍ1인당 도합 1건의 거래와 입찰이 가능합니다.<br>
ㆍ기본금쌀 1000은 거래에 사용되지 못합니다.<br>
ㆍ유찰될 때는 거래 과실자에게 거래금의 1%가 벌금으로 부과됩니다.<br>
ㆍ<font color=magenta>10단위로 거래가 가능합니다. 1자리는 반올림 처리 됩니다.</font><br>
ㆍ<font color=red>★ 최고가 거래 ★</font> 혹은 <font color=red>★ 최저가 거래 ★</font> 는 암거래 및 악용의 가능성이니 감시 부탁드립니다.<br>
ㆍ거래와 입찰은 취소가 불가능하니 주의하세요!<br>
ㆍ<font color=cyan>Hint</font>) 단가는 금/쌀로 쌀1을 거래하기 위한 금의 양입니다.<br>
ㆍ<font color=cyan>Hint</font>) 단가가 높으면(>1.00) 쌀이 비싸므로 판매가 이득입니다.<br>
ㆍ<font color=cyan>Hint</font>) 단가가 낮으면(<1.00) 금이 비싸므로 구매가 이득입니다.<br>
ㆍ즐거운 거래!
</font>
</td>
</tr>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
-217
View File
@@ -1,217 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$v = new Validator($_POST + $_GET);
$v->rule('required', 'gen')
->rule('integer', 'gen');
$btn = Util::getReq('btn');
$gen = Util::getReq('gen', 'int', 0);
$reqQueryType = Util::getReq('query_type', 'string', null);
// $queryTypeText, $reqArgType(0=>None, 1=>AdditionalColumn, 2=>rankVal, 3=>aux), $comp
$queryMap = [
'turntime' => ['최근턴', 0, function ($lhs, $rhs) {
return - ($lhs['turntime'] <=> $rhs['turntime']);
}],
'recent_war' => ['최근전투', 1, function ($lhs, $rhs) {
return - ($lhs['recent_war'] <=> $rhs['recent_war']);
}],
'name' => ['장수명', 0, function ($lhs, $rhs) {
if ($lhs['npc'] !== $rhs['npc']) {
return $lhs['npc'] <=> $rhs['npc'];
}
return $lhs['name'] <=> $rhs['name'];
}],
'warnum' => ['전투수', 2, function ($lhs, $rhs) {
return - ($lhs['warnum'] <=> $rhs['warnum']);
}]
];
if ($reqQueryType === null || !key_exists($reqQueryType, $queryMap)) {
$reqQueryType = Util::array_first_key($queryMap);
}
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("감찰부", 2);
//전투 추진을 위해 갱신
TurnExecutionHelper::executeAllCommand();
$gameStor->resetCache();
$testGeneralNationID = $db->queryFirstField('SELECT nation FROM general WHERE no = %i', $gen);
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID);
$nationID = $me['nation'];
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
$permission = checkSecretPermission($me);
if ($permission < 0) {
echo '국가에 소속되어있지 않습니다.';
die();
} else if ($permission < 1) {
echo "권한이 부족합니다. 수뇌부가 아니거나 사관년도가 부족합니다.";
die();
}
//잘못된 접근
if ($testGeneralNationID != $nationID) {
$gen = 0;
}
if ($btn == '정렬하기') {
$gen = 0;
}
[$queryTypeText, $reqArgType, $comp] = $queryMap[$reqQueryType];
if ($reqArgType === 0) {
$generalBasicList = $db->query('SELECT no, name, npc, turntime, officer_level FROM general WHERE nation = %i', $nationID);
} else if ($reqArgType === 1) {
$generalBasicList = $db->query('SELECT no, name, npc, turntime, officer_level, %b FROM general WHERE nation = %i', $reqQueryType, $nationID);
} else if ($reqArgType === 2) {
$generalBasicList = $db->query(
'SELECT no, name, npc, turntime, officer_level, value as %b
FROM general LEFT JOIN rank_data
ON general.no = rank_data.general_id
WHERE rank_data.type = %s AND general.nation = %i',
$reqQueryType,
$reqQueryType,
$nationID
);
} else if ($reqArgType === 3) {
$generalBasicList = array_map(function ($arr) {
$arr['aux'] = Json::decode($arr['aux']);
return $arr;
}, $db->query('SELECT no, name, npc, turntime, officer_level, aux FROM general WHERE nation = %i', $nationID));
} else {
throw new \sammo\MustNotBeReachedException();
}
usort($generalBasicList, $comp);
if (!$gen) {
$gen = $generalBasicList[0]['no'];
}
$showGeneral = General::createGeneralObjFromDB($gen);
?>
<!DOCTYPE html>
<html>
<head>
<title><?= UniqueConst::$serverName ?>: 감찰부</title>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('ts', ['common']) ?>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>감 찰 부<br><?= closeButton() ?></td>
</tr>
<tr>
<td>
<form name=form1 method=post>
정렬순서 :
<select name='query_type' size=1>
<?php foreach ($queryMap as $queryType => [$queryTypeText,]) : ?>
<option <?= $queryType == $reqQueryType ? 'selected' : '' ?> value='<?= $queryType ?>'><?= $queryTypeText ?></option>
<?php endforeach; ?>
</select>
<input type=submit name=btn value='정렬하기'>
대상장수 :
<select name=gen size=1>
<?php foreach ($generalBasicList as $general) : ?>
<option <?= $gen == $general['no'] ? 'selected' : '' ?> value='<?= $general['no'] ?>'><?= $general['officer_level'] > 4 ? "*{$general['name']}*" : $general['name'] ?> (<?= substr($general['turntime'], 14, 5) ?>)</option>
<?php endforeach; ?>
</select>
<input type=submit name=btn value='조회하기'>
</form>
</td>
</tr>
</table>
<table width=1000 align=center class='tb_layout bg0'>
<tr>
<td width=50% align=center class='bg1'>
<font color=skyblue size=3>장 수 정 보</font>
</td>
<td width=50% align=center class='bg1'>
<font color=orange size=3>장 수 열 전</font>
</td>
</tr>
<tr>
<td valign=top>
<?php generalInfo($showGeneral);
generalInfo2($showGeneral); ?>
</td>
<td valign=top>
<?= formatHistoryToHTML(getGeneralHistoryLogAll($gen)) ?>
</td>
</tr>
<tr>
<td align=center class='bg1'>
<font color=orange size=3>전투 기록</font>
</td>
<td align=center class='bg1'>
<font color=orange size=3>전투 결과</font>
</td>
</tr>
<tr>
<td valign=top>
<?= formatHistoryToHTML(getBattleDetailLogRecent($gen, 24)) ?>
</td>
<td valign=top>
<?= formatHistoryToHTML(getBattleResultRecent($gen, 24)) ?>
</td>
</tr>
<?php if ($showGeneral->getNPCType() > 1 || $permission >= 2) : ?>
<tr>
<td align=center class='bg1'>
<font color=orange size=3>개인 기록</font>
</td>
<td align=center class='bg1'>
<font color=orange size=3>&nbsp;</font>
</td>
</tr>
<tr>
<td valign=top>
<?= formatHistoryToHTML(getGeneralActionLogRecent($gen, 24)) ?>
</td>
<td valign=top>
</td>
</tr>
<?php endif; ?>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= closeButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</body>
</html>
+139 -105
View File
@@ -2,6 +2,10 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralLiteQueryMode;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\RankColumn;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
//로그인 검사 //로그인 검사
@@ -16,60 +20,91 @@ TurnExecutionHelper::executeAllCommand();
$generalID = $session->generalID; $generalID = $session->generalID;
//NOTE: general_id만 빼기 귀찮음.
$myBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID);
$myBet = array_splice($myBet, -16);
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0');
$globalBet = array_splice($globalBet, -16);
$me = $db->queryFirstRow('SELECT no,tournament,con,turntime from general where owner=%i', $userID);
$myBetTotal = array_sum($myBet);
$globalBetTotal = array_sum($globalBet);
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'develcost']); $me = $db->queryFirstRow(
'SELECT no,tournament,refresh_score,turntime FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id where owner=%i', $userID
);
$con = checkLimit($me['con']); $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'turnterm', 'develcost']);
if ($con >= 2) { $turnTerm = $admin['turnterm'];
$limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
switch ($admin['tnmt_type']) { switch ($admin['tnmt_type']) {
default: case convertTournamentType('전력전'):
throw new \RuntimeException('Invalid tnmt_type'); $tnmt_type = "전력전";
case 0: $color = "cyan";
$tnmt_type = "<font color=cyan>전력전</font>";
$tp = "total"; $tp = "total";
$tp2 = "종합"; $tp2 = "종합";
$tp3 = "total"; $tp3 = "total";
break; break;
case 1: case convertTournamentType('통솔전'):
$tnmt_type = "<font color=cyan>통솔전</font>"; $tnmt_type = "통솔전";
$color = "cyan";
$tp = "leadership"; $tp = "leadership";
$tp2 = "통솔"; $tp2 = "통솔";
$tp3 = "leadership"; $tp3 = "leadership";
break; break;
case 2: case convertTournamentType('일기토'):
$tnmt_type = "<font color=cyan>일기토</font>"; $tnmt_type = "일기토";
$color = "cyan";
$tp = "strength"; $tp = "strength";
$tp2 = "무력"; $tp2 = "무력";
$tp3 = "strength"; $tp3 = "strength";
break; break;
case 3: case convertTournamentType('설전'):
$tnmt_type = "<font color=cyan>설전</font>"; $tnmt_type = "설전";
$color = "cyan";
$tp = "intel"; $tp = "intel";
$tp2 = "지력"; $tp2 = "지력";
$tp3 = "intel"; $tp3 = "intel";
break; break;
default:
throw new \RuntimeException('Invalid tnmt_type');
} }
$bettingID = $gameStor->last_tournament_betting_id ?? 0;
$myBet = [];
$globalBet = [];
if ($bettingID != 0) {
$betting = $bettingID != 0 ? new Betting($bettingID) : null;
$info = $betting->getInfo();
foreach ($db->queryAllLists(
'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i',
$bettingID
) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) {
$bettingKey = Json::decode($bettingTypeKey)[0];
if ($betGeneralID == $generalID) {
$myBet[$bettingKey] = $amount;
}
if (key_exists($bettingKey, $globalBet)) {
$globalBet[$bettingKey] += $amount;
} else {
$globalBet[$bettingKey] = $amount;
}
}
} else {
$info = getDummyBettingInfo($tnmt_type);
}
$myBetTotal = array_sum($myBet);
$globalBetTotal = array_sum($globalBet);
$str1 = getTournament($admin['tournament']); $str1 = getTournament($admin['tournament']);
$str2 = getTournamentTime(); $str2 = getTournamentTime();
if ($str2) { if ($str2) {
$str2 = ', ' . $str2; $str2 = ', ' . $str2;
} }
$str3 = getTournamentTerm(); $str3 = getTournamentTermText($turnTerm);
if ($str3) { if ($str3) {
$str3 = ', ' . $str3; $str3 = ', ' . $str3;
} }
@@ -77,19 +112,26 @@ if ($str3) {
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($con == 1) { <?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?> } ?>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 베팅장</title> <title><?= UniqueConst::$serverName ?>: 베팅장</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'betting']) ?> <?= WebUtil::printDist('ts', ['common', 'betting']) ?>
<?= WebUtil::printStaticValues([
'staticValues'=>[
'bettingID'=> $bettingID
]
])?>
</head> </head>
<body> <body>
@@ -100,11 +142,11 @@ if ($str3) {
</table> </table>
<table align=center width=1120 class='tb_layout bg0'> <table align=center width=1120 class='tb_layout bg0'>
<tr> <tr>
<td colspan=16><input type=button value='갱신' onclick='location.reload()'></td> <td colspan=16><button type="button" class="btn btn-secondary" onclick='location.reload()'>갱신</button></td>
</tr> </tr>
<tr> <tr>
<td colspan=16 align=center> <td colspan=16 align=center>
<font color=white size=6><?= $tnmt_type ?> (<?= $str1 . $str2 . $str3 ?>)</font> <font color=white size=6><span style="color:<?= $color ?>"><?= $tnmt_type ?></span> (<?= $str1 . $str2 . $str3 ?>)</font>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -132,11 +174,8 @@ if ($str3) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) {
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>"; $general['name'] = formatName($general['name'], $general['npc']);
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
echo "<td colspan=16>{$general['name']}</td>"; echo "<td colspan=16>{$general['name']}</td>";
} }
@@ -162,11 +201,7 @@ if ($str3) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -208,11 +243,7 @@ if ($str3) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -254,11 +285,7 @@ if ($str3) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -280,7 +307,6 @@ if ($str3) {
for ($i = 0; $i < 8; $i++) { for ($i = 0; $i < 8; $i++) {
echo "<td colspan=2>{$gen[$i]}</td>"; echo "<td colspan=2>{$gen[$i]}</td>";
} }
echo " echo "
</tr> </tr>
<tr align=center>"; <tr align=center>";
@@ -288,7 +314,7 @@ if ($str3) {
for ($i = 0; $i < 8; $i++) { for ($i = 0; $i < 8; $i++) {
$cent[$i] = "<font color=white>"; $cent[$i] = "<font color=white>";
} }
$generalList = $db->query('SELECT npc,name,win from tournament where grp>=20 order by grp, grp_no LIMIT 16'); $generalList = $db->query('SELECT npc,name,win,leadership,strength,intel,leadership+strength+intel as total from tournament where grp>=20 order by grp, grp_no LIMIT 16');
while (count($generalList) < 16) { while (count($generalList) < 16) {
$generalList[] = [ $generalList[] = [
'name' => '-', 'name' => '-',
@@ -300,11 +326,7 @@ if ($str3) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -312,6 +334,11 @@ if ($str3) {
$line[$i] = "<font color=white>"; $line[$i] = "<font color=white>";
} }
$gen[$i] = $general['name']; $gen[$i] = $general['name'];
if (array_key_exists($tp, $general)) {
$stat[$i] = $general[$tp];
} else {
$stat[$i] = "-";
}
} }
for ($i = 0; $i < 8; $i++) { for ($i = 0; $i < 8; $i++) {
$cent[$i] = $cent[$i] . "┻" . "</font>"; $cent[$i] = $cent[$i] . "┻" . "</font>";
@@ -319,45 +346,48 @@ if ($str3) {
$line[$i * 2 + 1] = $line[$i * 2 + 1] . "━━┓" . "</font>"; $line[$i * 2 + 1] = $line[$i * 2 + 1] . "━━┓" . "</font>";
echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>"; echo "<td colspan=2>{$line[$i * 2]}{$cent[$i]}{$line[$i * 2 + 1]}</td>";
} }
echo "
</tr>
<tr align=center>";
for ($i = 0; $i < 16; $i++) {
echo "<td width=70>{$gen[$i]}</td>";
}
$bet = [];
$gold = [];
for ($i = 0; $i < 16; $i++) {
if ($globalBet[$i] == 0) {
$bet[$i] = "∞";
} else {
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2);
}
}
for ($i = 0; $i < 16; $i++) {
if (!is_numeric($bet[$i])) {
$gold[$i] = 0;
} else {
$gold[$i] = Util::round($myBet[$i] * $bet[$i]);
}
}
?> ?>
</tr> </tr>
<tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70><?= $gen[$i] ?></td>
<?php } ?>
</tr>
<tr align=center>
<?php for ($i = 0; $i < 16; $i++) { ?>
<td width=70 style="font-size: 14px"><?= $stat[$i] ?></td>
<?php } ?>
</tr>
</table> </table>
<table align=center width=1120 class='tb_layout bg0'> <table align=center width=1120 style="table-layout: fixed" class='tb_layout bg0'>
<tr align=center> <tr align=center>
<td height=10 colspan=16></td> <td height=10 colspan=16></td>
</tr> </tr>
<?php <?php
$bet = [];
$gold = [];
$keyMap = [];
foreach ($info->candidates as $key => $candidate) {
$keyMap[$candidate->aux['idx']] = $key;
}
foreach ($globalBet as $key => $amount) {
if ($amount == 0) {
$bet[$key] = "∞";
$gold[$key] = 0;
} else {
$rewardRatio = round($globalBetTotal / $amount, 2);
$bet[$key] = $rewardRatio;
$gold[$key] = $rewardRatio * ($myBet[$key] ?? 0);
}
}
echo " echo "
<tr align=center>"; <tr align=center>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td width=70><font color=skyblue>{$bet[$i]}</font></td>"; $amount = $bet[$keyMap[$i] ?? -1] ?? 0;
echo "<td width=70><font color=skyblue>{$amount}</font></td>";
} }
?> ?>
</tr> </tr>
@@ -381,8 +411,9 @@ if ($str3) {
</tr> </tr>
<tr align=center> <tr align=center>
<?php <?php
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td><font color=orange>{$myBet[$i]}</font></td>"; $amount = $myBet[$keyMap[$i] ?? -1] ?? 0;
echo "<td><font color=orange>{$amount}</font></td>";
} }
?> ?>
</tr> </tr>
@@ -406,8 +437,9 @@ if ($str3) {
</tr> </tr>
<tr align=center> <tr align=center>
<?php <?php
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td><font color=cyan>{$gold[$i]}</font></td>"; $amount = $gold[$keyMap[$i] ?? -1] ?? 0;
echo "<td><font color=cyan>{$amount}</font></td>";
} }
echo " echo "
@@ -416,12 +448,13 @@ if ($str3) {
if ($admin['tournament'] == 6) { if ($admin['tournament'] == 6) {
echo " echo "
<tr align=center>"; <tr align=center style='height:2.5em;'>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
$key = $keyMap[$i] ?? -1;
echo " echo "
<td> <td>
<select size=1 id='target_{$i}' style=color:white;background-color:black;> <select size=1 id='target_{$key}' style='color:white;background-color:black;padding:0.2rem 0.1rem;'>
<option style=color:white; value=10>금10</option> <option style=color:white; value=10>금10</option>
<option style=color:white; value=20>금20</option> <option style=color:white; value=20>금20</option>
<option style=color:white; value=50>금50</option> <option style=color:white; value=50>금50</option>
@@ -435,11 +468,12 @@ if ($str3) {
echo " echo "
</tr> </tr>
<tr align=center>"; <tr align=center style='height:2.2em;'>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
$key = $keyMap[$i] ?? -1;
echo " echo "
<td><input type=button class='submitBtn' data-target='{$i}' value=베팅! style=width:100%;color:white;background-color:black;></td>"; <td><input type=button class='submitBtn' data-target='{$key}' value=베팅! style='width:100%;color:white;padding:0.2rem 0.1rem;background-color:black;'></td>";
} }
echo "</tr>"; echo "</tr>";
@@ -473,28 +507,28 @@ if ($str3) {
$tournamentType = [ $tournamentType = [
'전 력 전' => [ '전 력 전' => [
'종합', '종합',
function (General $general) { function (GeneralLite $general) {
return $general->getVar('leadership') + $general->getVar('strength') + $general->getVar('intel'); return $general->getVar('leadership') + $general->getVar('strength') + $general->getVar('intel');
}, },
'tt', 'tt',
], ],
'통 솔 전' => [ '통 솔 전' => [
'통솔', '통솔',
function (General $general) { function (GeneralLite $general) {
return $general->getVar('leadership'); return $general->getVar('leadership');
}, },
'tl', 'tl',
], ],
'일 기 토' => [ '일 기 토' => [
'무력', '무력',
function (General $general) { function (GeneralLite $general) {
return $general->getVar('strength'); return $general->getVar('strength');
}, },
'ts', 'ts',
], ],
'설 전' => [ '설 전' => [
'지력', '지력',
function (General $general) { function (GeneralLite $general) {
return $general->getVar('intel'); return $general->getVar('intel');
}, },
'ti', 'ti',
@@ -526,17 +560,17 @@ if ($str3) {
<td align=center>勝</td> <td align=center>勝</td>
</tr> </tr>
<?php <?php
$prizeColumn = "{$rankColumn}p"; $prizeColumn = RankColumn::from("{$rankColumn}p");
$gameColumn = "{$rankColumn}g"; $gameColumn = RankColumn::from("{$rankColumn}g");
$winColumn = "{$rankColumn}w"; $winColumn = RankColumn::from("{$rankColumn}w");
$drawColumn = "{$rankColumn}d"; $drawColumn = RankColumn::from("{$rankColumn}d");
$loseColumn = "{$rankColumn}l"; $loseColumn = RankColumn::from("{$rankColumn}l");
$tournamentRankerList = General::createGeneralObjListFromDB( $tournamentRankerList = GeneralLite::createObjListFromDB(
$db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn), $db->queryFirstColumn('SELECT general_id FROM rank_data WHERE `type`= %s ORDER BY value DESC LIMIT 40', $gameColumn->value),
[$prizeColumn, $gameColumn, $winColumn, $drawColumn, $loseColumn, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'], [$prizeColumn->value, $gameColumn->value, $winColumn->value, $drawColumn->value, $loseColumn->value, 'leadership', 'strength', 'intel', 'no', 'npc', 'name'],
0 GeneralLiteQueryMode::Core
); );
usort($tournamentRankerList, function (General $lhs, General $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) { usort($tournamentRankerList, function (GeneralLite $lhs, GeneralLite $rhs) use ($gameColumn, $winColumn, $drawColumn, $loseColumn) {
$result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn)); $result = - ($lhs->getRankVar($gameColumn) <=> $rhs->getRankVar($gameColumn));
if ($result !== 0) return $result; if ($result !== 0) return $result;
$result = - ( $result = - (
+10 -6
View File
@@ -13,9 +13,11 @@ $userID = Session::getUserID();
$userGrade = Session::getUserGrade(); $userGrade = Session::getUserGrade();
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("현재도시", 1); increaseRefresh("현재도시", 1);
$lastExecute = substr($gameStor->turntime, 5, 14);
$me = $db->queryFirstRow('SELECT no,nation,officer_level,city from general where owner=%i', $userID); $me = $db->queryFirstRow('SELECT no,nation,officer_level,city from general where owner=%i', $userID);
$myNation = $db->queryFirstRow('SELECT nation,level,spy FROM nation WHERE nation=%i', $me['nation']) ?? [ $myNation = $db->queryFirstRow('SELECT nation,level,spy FROM nation WHERE nation=%i', $me['nation']) ?? [
'nation' => 0, 'nation' => 0,
@@ -32,6 +34,7 @@ $templates = new \League\Plates\Engine('templates');
<head> <head>
<title><?= UniqueConst::$serverName ?>: 도시정보</title> <title><?= UniqueConst::$serverName ?>: 도시정보</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
@@ -53,6 +56,7 @@ $templates = new \League\Plates\Engine('templates');
font-size: x-small; font-size: x-small;
} }
</style> </style>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'currentCity']) ?> <?= WebUtil::printDist('ts', ['common', 'currentCity']) ?>
</head> </head>
@@ -207,7 +211,7 @@ $templates = new \League\Plates\Engine('templates');
$city['trade'] = "- "; $city['trade'] = "- ";
} }
$dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'], 2)[0]; $dbColumns = General::mergeQueryColumn(['npc', 'defence_train', 'no', 'picture', 'imgsvr', 'name', 'injury', 'leadership', 'strength', 'intel', 'officer_level', 'nation', 'crewtype', 'crew', 'train', 'atmos'])[0];
if ($showDetailedInfo) { if ($showDetailedInfo) {
$generals = $db->query( $generals = $db->query(
'SELECT %l from general where city=%i order by turntime', 'SELECT %l from general where city=%i order by turntime',
@@ -323,8 +327,7 @@ $templates = new \League\Plates\Engine('templates');
if ($ourGeneral && !$isNPC) { if ($ourGeneral && !$isNPC) {
$turnText = []; $turnText = [];
$generalObj = new General($general, null, null, null, null, null, false); foreach ($generalTurnList[$general['no']] as $turnRawIdx => $turn) {
foreach ($generalTurnList[$generalObj->getID()] as $turnRawIdx => $turn) {
$turnIdx = $turnRawIdx + 1; $turnIdx = $turnRawIdx + 1;
$turnText[] = "{$turnIdx} : $turn"; $turnText[] = "{$turnIdx} : $turn";
} }
@@ -337,6 +340,7 @@ $templates = new \League\Plates\Engine('templates');
'ourGeneral' => $ourGeneral, 'ourGeneral' => $ourGeneral,
'iconPath' => GetImageURL($general['imgsvr']) . '/' . $general['picture'], 'iconPath' => GetImageURL($general['imgsvr']) . '/' . $general['picture'],
'isNPC' => $isNPC, 'isNPC' => $isNPC,
'npc' => $general['npc'],
'wounded' => $wounded, 'wounded' => $wounded,
'name' => $name, 'name' => $name,
'nameText' => $nameText, 'nameText' => $nameText,
@@ -364,7 +368,7 @@ $templates = new \League\Plates\Engine('templates');
} }
$generalsName = array_map(function ($gen) { $generalsName = array_map(function ($gen) {
return getColoredName($gen['name'], $gen['npc']); return formatName($gen['name'], $gen['npc']);
}, $generals); }, $generals);
$enemyCrew = 0; $enemyCrew = 0;
@@ -445,7 +449,7 @@ $templates = new \League\Plates\Engine('templates');
<table align=center width=1000 class='tb_layout bg2'> <table align=center width=1000 class='tb_layout bg2'>
<tr> <tr>
<td colspan=11 align=center style='color:<?= newColor($cityNation['color']) ?>; background:<?= $cityNation['color'] ?>'>【 <?= CityConst::$regionMap[$city['region']] ?> | <?= CityConst::$levelMap[$city['level']] ?> 】 <?= $city['name'] ?></td> <td colspan=11 align=center style='color:<?= newColor($cityNation['color']) ?>; background:<?= $cityNation['color'] ?>'>【 <?= CityConst::$regionMap[$city['region']] ?> | <?= CityConst::$levelMap[$city['level']] ?> 】 <?= $city['name'] ?></td>
<td style='color:<?= newColor($cityNation['color']) ?>; background:<?= $cityNation['color'] ?>' class='center'><?= date('m-d H:i:s') ?></td> <td style='color:<?= newColor($cityNation['color']) ?>; background:<?= $cityNation['color'] ?>' class='center'><?= $lastExecute ?></td>
</tr> </tr>
<tr> <tr>
<td align=center width=48 class=bg1>주민</td> <td align=center width=48 class=bg1>주민</td>
-236
View File
@@ -1,236 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("중원정보", 1);
$mapTheme = $gameStor->map_theme ?? 'che';
$me = $db->queryFirstRow('SELECT no,nation FROM general WHERE owner=%i', $userID);
$myNationID = $me['nation'];
$nations = array_filter(getAllNationStaticInfo(), function (array $nation) {
return $nation['level'];
});
uasort($nations, function (array $lhs, array $rhs) {
return - ($lhs['power'] <=> $rhs['power']);
});
$nationCnt = count($nations);
foreach ($db->queryAllLists('SELECT nation, count(city) FROM city WHERE nation != 0 GROUP BY nation') as [$nationID, $cityCnt]) {
$nations[$nationID]['city_cnt'] = $cityCnt;
}
$realConflict = [];
foreach ($db->queryAllLists('SELECT city, `name`, conflict FROM city WHERE conflict!=%s', '{}') as [
$cityID,
$cityName,
$rawConflict
]) {
$rawConflict = Json::decode($rawConflict);
if (count($rawConflict) < 2) {
continue;
}
$sum = array_sum($rawConflict);
$conflict = [];
foreach ($rawConflict as $nationID => $killnum) {
$conflict[$nationID] = [
'killnum' => $killnum,
'percent' => round(100 * $killnum / $sum, 1),
'name' => $nations[$nationID]['name'],
'color' => $nations[$nationID]['color']
];
}
$realConflict[] = [$cityID, $cityName, $conflict];
};
$diplomacyList = [];
foreach ($db->queryAllLists('SELECT me, you, state FROM diplomacy') as [$me, $you, $state]) {
if (!key_exists($me, $diplomacyList)) {
$diplomacyList[$me] = [];
}
$diplomacyList[$me][$you] = $state;
}
$cellWidth = intdiv(888, max(1, $nationCnt));
$defaultStateChar = '?';
$sameNationStateChar = '';
$infomativeStateCharMap = [
0 => '<span style="color:red;">★</span>',
1 => '<span style="color:magenta;">▲</span>',
2 => 'ㆍ',
7 => '<span style="color:green;">@</span>'
];
$neutralStateCharMap = [
0 => '<span style="color:red;">★</span>',
1 => '<span style="color:magenta;">▲</span>'
];
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 중원 정보</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS('d_shared/base_map.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/map.css') ?>
<?= WebUtil::printCSS('css/history.css') ?>
<?= WebUtil::printDist('ts', ['common', 'map']) ?>
<script>
window.serverNick = '<?= DB::prefix() ?>';
window.serverID = '<?= UniqueConst::$serverID ?>';
$(function() {
reloadWorldMap({
neutralView: true,
showMe: true,
useCachedMap: true
});
});
</script>
</head>
<body>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td>중 원 정 보<br><?= backButton() ?></td>
</tr>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=<?= $nationCnt + 1 ?> align=center bgcolor=blue>외 교 현 황</td>
</tr>
<tr>
<td align=center width=130 style=background-color:<?= GameConst::$basecolor2 ?>;>&nbsp;</td>
<?php foreach ($nations as $nation) : ?>
<td align=center width=<?= $cellWidth ?> style='background-color:<?= $nation['color'] ?>;color:<?= newColor($nation['color']) ?>'><?= $nation['name'] ?></td>
<?php endforeach; ?>
</tr>
<?php foreach ($nations as $me => $meNation) : ?>
<tr style='text-align:center;'>
<td align=center style='background-color:<?= $meNation['color'] ?>;color:<?= newColor($meNation['color']) ?>'><?= $meNation['name'] ?></td>
<?php foreach (array_keys($nations) as $you) : ?>
<td <?= ($me == $myNationID || $you == $myNationID) ? 'style="background-color:' . GameConst::$basecolor3 . '"' : '' ?>><?php
if ($me == $you) {
echo $sameNationStateChar;
} else if ($me == $myNationID || $you == $myNationID || $session->userGrade >= 5) {
echo $infomativeStateCharMap[$diplomacyList[$me][$you]] ?? $defaultStateChar;
} else {
echo $neutralStateCharMap[$diplomacyList[$me][$you]] ?? $defaultStateChar;
}
?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<tr>
<td colspan=<?= $nationCnt + 1 ?> align=center>불가침 : <font color=limegreen>@</font>, 통상 : ㆍ, 선포 : <font color=magenta>▲</font>, 교전 : <font color=red>★</font>
</td>
</tr>
</table>
<?php if ($realConflict) : ?>
<br>
<table align='center' width=1000 class='tb_layout bg0'>
<tr>
<td colspan=2 align=center bgcolor=magenta>분 쟁 현 황</td>
</tr>
<?php foreach ($realConflict as list($cityID, $cityName, $conflict)) : ?>
<tr>
<td align=center width=48><?= $cityName ?></td>
<td style='width:948px;position:relative;'>
<table class='tb_layout bg0' style='width:100%;'>
<?php foreach ($conflict as $item) : ?>
<tr>
<td width=130 align=right style='color:<?= newColor($item['color']) ?>;background-color:<?= $item['color'] ?>;'><?= $item['name'] ?>&nbsp;</td>
<td width=48 align=right><?= (float)$item['percent'] ?> %&nbsp;</td>
<td width=*>
<div style='display:inline-block;width:<?= $item['percent'] ?>%;background-color:<?= $item['color'] ?>;'>&nbsp;</div>
</td>
</tr>
<?php endforeach; ?>
</table>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td colspan=2 height=5 class='bg1'></td>
</tr>
</table>
<?php endif; ?>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=5 align=center bgcolor=green>
<font size=3>중 원 지 도</font>
</td>
</tr>
<tr>
<td width=698 height=420>
<?= getMapHtml($mapTheme) ?>
</td>
<td id='nation_list_frame'>
<table id='nation_list'>
<thead>
<tr>
<th width=130>국명</th>
<th width=70>국력</th>
<th width=45>장수</th>
<th width=45>속령</th>
</tr>
</thead>
<tbody>
<?php foreach ($nations as $nation) : ?>
<tr>
<td><span style='color:<?= newColor($nation['color']) ?>;background-color:<?= $nation['color'] ?>'><?= $nation['name'] ?></td>
<td style='text-align:right'><?= number_format($nation['power']) ?></td>
<td style='text-align:right'><?= number_format($nation['gennum']) ?></td>
<td style='text-align:right'><?= number_format($nation['city_cnt']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot></tfoot>
</table>
</td>
</tr>
</table>
<br>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?></td>
</tr>
</table>
</body>
</html>
+10 -5
View File
@@ -19,12 +19,15 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("암행부", 1); increaseRefresh("암행부", 1);
$me = $db->queryFirstRow('SELECT no,nation,officer_level,con,turntime,belong,permission,penalty from general where owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,nation,officer_level,refresh_score,turntime,belong,permission,penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation=%i', $me['nation']); $nationLevel = $db->queryFirstField('SELECT level FROM nation WHERE nation=%i', $me['nation']);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
@@ -45,18 +48,20 @@ $templates = new \League\Plates\Engine('templates');
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($con == 1) { <?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!"); MessageBox("접속제한이 얼마 남지 않았습니다!");
} ?> } ?>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 암행부</title> <title><?= UniqueConst::$serverName ?>: 암행부</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common']) ?> <?= WebUtil::printDist('ts', ['common']) ?>
</head> </head>
@@ -172,7 +177,7 @@ $templates = new \League\Plates\Engine('templates');
$general['expLevelText'] = getExpLevel($general['experience']); $general['expLevelText'] = getExpLevel($general['experience']);
$general['nameText'] = getColoredName($general['name'], $general['npc']); $general['nameText'] = formatName($general['name'], $general['npc']);
$general['modeText'] = formatDefenceTrain($general['defence_train']); $general['modeText'] = formatDefenceTrain($general['defence_train']);
$general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name ?? '-'; $general['crewtypeText'] = GameUnitConst::byId($general['crewtype'])->name ?? '-';
+49 -48
View File
@@ -25,12 +25,24 @@ if ($meLevel == 0) {
$nation = $db->queryFirstRow('SELECT nation,name,level,color,chief_set from nation where nation=%i', $nationID); //국가정보 $nation = $db->queryFirstRow('SELECT nation,name,level,color,chief_set from nation where nation=%i', $nationID); //국가정보
if ($meLevel >= 5) {
$candidateStrength = $db->query('SELECT no,name,officer_level,city,npc from general where nation=%i and officer_level!=12 and strength>=%i order by npc,binary(name)', $nationID, GameConst::$chiefStatMin);
$candidateIntel = $db->query('SELECT no,name,officer_level,city,npc from general where nation=%i and officer_level!=12 and intel>=%i order by npc,binary(name)', $nationID, GameConst::$chiefStatMin);
$candidateAny = $db->query('SELECT no,name,officer_level,city,npc,leadership,strength,intel,killturn from general where nation=%i and officer_level!=12 order by npc,binary(name)', $nationID); //추방 때문에 조금 더 김
} else {
$candidateStrength = [];
$candidateIntel = [];
$candidateAny = [];
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 인사부</title> <title><?= UniqueConst::$serverName ?>: 인사부</title>
@@ -43,6 +55,7 @@ $nation = $db->queryFirstRow('SELECT nation,name,level,color,chief_set from nati
var chiefStatMin = <?= GameConst::$chiefStatMin ?>; var chiefStatMin = <?= GameConst::$chiefStatMin ?>;
var myLevel = <?= $meLevel ?>; var myLevel = <?= $meLevel ?>;
</script> </script>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'bossInfo']) ?> <?= WebUtil::printDist('ts', ['common', 'bossInfo']) ?>
<?php <?php
@@ -180,61 +193,21 @@ $nation = $db->queryFirstRow('SELECT nation,name,level,color,chief_set from nati
<td colspan=5><?= $eaglestr ?></td> <td colspan=5><?= $eaglestr ?></td>
</tr> </tr>
</table> </table>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr> <tr>
<td colspan=6 height=5></td> <td colspan=4 height=5></td>
</tr> </tr>
<tr> <tr>
<td colspan=2 align=center bgcolor=red>추 방</td> <td colspan=4 align=center bgcolor=blue>수 뇌 부 임 명</td>
</tr> </tr>
<tr> <tr>
<td width=498 align=right class='bg1'>대상 장수</td> <?php $officerLevelText = getOfficerLevelText(11, $nation['level']); ?>
<td width=498> <td width=98 align=right class='bg1'><?= getOfficerLevelText(12, $nation['level']) ?></td>
<td width=398><?= $level[12]['name'] ?> 【<?= CityConst::byID($level[12]['city'])->name ?>】</td>
<td width=98 align=right class='bg1'><?= $officerLevelText ?></td>
<td width=398>
<?php <?php
if ($meLevel >= 5) {
$candidateStrength = $db->query('SELECT no,name,officer_level,city,npc from general where nation=%i and officer_level!=12 and strength>=%i order by npc,binary(name)', $nationID, GameConst::$chiefStatMin);
$candidateIntel = $db->query('SELECT no,name,officer_level,city,npc from general where nation=%i and officer_level!=12 and intel>=%i order by npc,binary(name)', $nationID, GameConst::$chiefStatMin);
$candidateAny = $db->query('SELECT no,name,officer_level,city,npc,leadership,strength,intel,killturn from general where nation=%i and officer_level!=12 order by npc,binary(name)', $nationID); //추방 때문에 조금 더 김
} else {
$candidateStrength = [];
$candidateIntel = [];
$candidateAny = [];
}
if ($meLevel >= 5 && !isOfficerSet($nation['chief_set'], $meLevel)) {
echo "
<select id='genlist_kick' size=1 style=color:white;background-color:black;>";
foreach ($candidateAny as $general) {
if ($general['no'] === $me['no']) {
continue;
}
echo "
<option data-officer_level='{$general['officer_level']}' data-name='{$general['name']}' value={$general['no']}>{$general['name']} <small>({$general['leadership']}/{$general['strength']}/{$general['intel']}, {$general['killturn']}턴)</small></option>";
}
echo "
</select>
<input type=$btn id='btn_kick' value=추방>";
}
$officerLevelText = getOfficerLevelText(11, $nation['level']);
echo "
</td>
</tr>
</table>
<table align=center width=1000 class='tb_layout bg0'>
<tr><td colspan=4 height=5></td></tr>
<tr><td colspan=4 align=center bgcolor=blue>수 뇌 부 임 명</td></tr>
<tr>
<td width=98 align=right class='bg1'>" . getOfficerLevelText(12, $nation['level']) . "</td>
<td width=398>{$level[12]['name']} 【" . CityConst::byID($level[12]['city'])->name . "】</td>
<td width=98 align=right class='bg1'>{$officerLevelText}</td>
<td width=398>
";
if ($meLevel >= 5 && !isOfficerSet($nation['chief_set'], 11)) { if ($meLevel >= 5 && !isOfficerSet($nation['chief_set'], 11)) {
echo " echo "
<select id='genlist_11' size=1 maxlength=15 style=color:white;background-color:black;> <select id='genlist_11' size=1 maxlength=15 style=color:white;background-color:black;>
@@ -553,6 +526,34 @@ $nation = $db->queryFirstRow('SELECT nation,name,level,color,chief_set from nati
<td colspan=5>※ <font color=orange>노란색</font>은 변경 불가능, 하얀색은 변경 가능 관직입니다.</td> <td colspan=5>※ <font color=orange>노란색</font>은 변경 불가능, 하얀색은 변경 가능 관직입니다.</td>
</tr> </tr>
</table> </table>
<table align=center width=1000 class='tb_layout bg0'>
<tr>
<td colspan=6 height=5></td>
</tr>
<tr>
<td colspan=2 align=center bgcolor=red>추 방</td>
</tr>
<tr>
<td width=498 align=right class='bg1'>대상 장수</td>
<td width=498>
<?php
if ($meLevel >= 5 && !isOfficerSet($nation['chief_set'], $meLevel)) : ?>
<select id='genlist_kick' size=1 style=color:white;background-color:black;>";
<?php foreach ($candidateAny as $general) : ?>
<?php if ($general['no'] === $me['no']) {
continue;
}
?>
<option data-officer_level='<?= $general['officer_level'] ?>' data-name='<?= $general['name'] ?>' value='<?= $general['no'] ?>'><?= $general['name'] ?> <small>(<?= $general['leadership'] ?>/<?= $general['strength'] ?>/<?= $general['intel'] ?>, <?= $general['killturn'] ?>턴)</small></option>
<?php endforeach; ?>
</select>
<input type=<?= $btn ?> id='btn_kick' value=추방>
<?php endif; ?>
</td>
</tr>
</table>
<br> <br>
<table align=center width=1000 class='tb_layout bg0'> <table align=center width=1000 class='tb_layout bg0'>
<tr> <tr>
+74 -58
View File
@@ -33,12 +33,14 @@ $sel = [$type => "selected"];
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 세력도시</title> <title><?= UniqueConst::$serverName ?>: 세력도시</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'extExpandCity']) ?> <?= WebUtil::printDist('ts', ['common', 'extExpandCity']) ?>
</head> </head>
@@ -71,7 +73,8 @@ $sel = [$type => "selected"];
</table> </table>
<?php <?php
$nation = getNationStaticInfo($me['nation']); //국가정보 $nation = $db->queryFirstRow('SELECT nation, name, color, type, level, capital, gennum, `power`, `rate` from nation WHERE nation = %i', $nationID); //국가정보
$nationTypeObj = buildNationTypeClass($nation['type']);
$officerList = []; $officerList = [];
foreach ($db->query('SELECT no,name,npc,city,officer_level,officer_city,belong FROM general WHERE nation = %i AND 2 <= officer_level AND officer_level <= 4', $nationID) as $officer) { foreach ($db->query('SELECT no,name,npc,city,officer_level,officer_city,belong FROM general WHERE nation = %i AND 2 <= officer_level AND officer_level <= 4', $nationID) as $officer) {
@@ -82,6 +85,17 @@ $sel = [$type => "selected"];
$officerList[$officerCityID][$officer['officer_level']] = $officer; $officerList[$officerCityID][$officer['officer_level']] = $officer;
} }
$generalList = $db->query('SELECT npc, name, city FROM general WHERE nation = %i', $me['nation']);
$cityGeneralList = [];
foreach ($generalList as $general) {
$cityID = $general['city'];
if (!key_exists($cityID, $cityGeneralList)) {
$cityGeneralList[$cityID] = [];
}
$cityGeneralList[$cityID][] = formatName($general['name'], $general['npc']);
}
$cityList = $db->query('SELECT *,pop/pop_max as poprate from city where nation=%i', $nationID); $cityList = $db->query('SELECT *,pop/pop_max as poprate from city where nation=%i', $nationID);
@@ -171,8 +185,12 @@ $sel = [$type => "selected"];
]; ];
$cityOfficerList = $officerList[$cityID] ?? []; $cityOfficerList = $officerList[$cityID] ?? [];
$effectiveOfficerCnt = 0;
foreach ($cityOfficerList as $cityOfficer) { foreach ($cityOfficerList as $cityOfficer) {
$officerName[$cityOfficer['officer_level']] = getColoredName($cityOfficer['name'], $cityOfficer['npc']); if ($cityOfficer['city'] == $cityID) {
$effectiveOfficerCnt += 1;
}
$officerName[$cityOfficer['officer_level']] = formatName($cityOfficer['name'], $cityOfficer['npc']);
} }
if ($type == 10 && $city['region'] != $region) { if ($type == 10 && $city['region'] != $region) {
@@ -187,62 +205,60 @@ $sel = [$type => "selected"];
$city['trade'] = "- "; $city['trade'] = "- ";
} }
echo "
<table align=center width=1000 class='tb_layout bg2'> $cityGoldIncome = $nation['rate'] / 20 * calcCityGoldIncome($city, $effectiveOfficerCnt, $nation['capital'] == $cityID, $nation['level'], $nationTypeObj);
<tr> $cityRiceIncome = $nation['rate'] / 20 * calcCityRiceIncome($city, $effectiveOfficerCnt, $nation['capital'] == $cityID, $nation['level'], $nationTypeObj);
<td colspan=12 style=color:" . newColor($nation['color']) . "; bgcolor={$nation['color']}><font size=2>【 " . CityConst::$regionMap[$city['region']] . " | " . CityConst::$levelMap[$city['level']] . " 】 {$city['name']}</font></td> $cityWallIncome = $nation['rate'] / 20 * calcCityWallRiceIncome($city, $effectiveOfficerCnt, $nation['capital'] == $cityID, $nation['level'], $nationTypeObj);
</tr>
<tr>
<td align=center width=46 class='bg1'>주민</td>
<td align=center width=140>{$city['pop']}/{$city['pop_max']}</td>
<td align=center width=46 class='bg1'>농업</td>
<td align=center width=140>{$city['agri']}/{$city['agri_max']}</td>
<td align=center width=46 class='bg1'>상업</td>
<td align=center width=140>{$city['comm']}/{$city['comm_max']}</td>
<td align=center width=46 class='bg1'>치안</td>
<td align=center width=140>{$city['secu']}/{$city['secu_max']}</td>
<td align=center width=46 class='bg1'>수비</td>
<td align=center width=140>{$city['def']}/{$city['def_max']}</td>
<td align=center width=46 class='bg1'>성벽</td>
<td align=center width=140>{$city['wall']}/{$city['wall_max']}</td>
</tr>
<tr>
<td align=center class='bg1'>민심</td>
<td align=center>" . round($city['trust'], 1) . "</td>
<td align=center class='bg1'>시세</td>
<td align=center>{$city['trade']}%</td>
<td align=center class='bg1'>인구</td>
<td align=center>" . round($city['pop'] / $city['pop_max'] * 100, 2) . " %</td>
<td align=center class='bg1'>태수</td>
<td align=center>";
echo $officerName[4];
echo "</td>
<td align=center class='bg1'>군사</td>
<td align=center>";
echo $officerName[3];
echo "</td>
<td align=center class='bg1'>종사</td>
<td align=center>";
echo $officerName[2];
echo "</td>
</tr>
<tr>
<td align=center class='bg1'>장수</td>
<td colspan=11>";
$generalList = $db->query('SELECT npc, name FROM general WHERE city = %i AND nation = %i', $city['city'], $me['nation']);
if (!$generalList) {
echo "-";
}
foreach ($generalList as $general) {
echo getColoredName($general['name'], $general['npc']) . ', ';
}
echo "
</td>
</tr>
</table>
";
}
?> ?>
<table align=center width=1000 class='tb_layout bg2'>
<tr>
<td colspan=10 style="color:<?= newColor($nation['color']) ?>; background-color:<?= $nation['color'] ?>;">
<font size=2>【 <?= CityConst::$regionMap[$city['region']] ?> | <?= CityConst::$levelMap[$city['level']] ?> 】 <?= $city['name'] ?></font>
</td>
</tr>
<tr style='text-align:center;'>
<td width=60 class='bg1'>주민</td>
<td width=140 class='pop-value'><?= $city['pop'] ?>/<?= $city['pop_max'] ?></td>
<td width=60 class='bg1'>인구율</td>
<td width=140 class='pop-prop-value'><?= round($city['pop'] / $city['pop_max'] * 100, 2) ?>%</td>
<td width=60 class='bg1'>자금 수입</td>
<td width=140 class='gold-income'><?= number_format($cityGoldIncome) ?></td>
<td width=60 class='bg1'>군량 수입</td>
<td width=140 class='rice-income'><?= number_format($cityRiceIncome) ?></td>
<td width=60 class='bg1'>둔전 수입</td>
<td width=140 class='wall-income'><?= number_format($cityWallIncome) ?></td>
</tr>
<tr style='text-align:center;'>
<td class='bg1'>농업</td>
<td class='agri-value'><?= $city['agri'] ?>/<?= $city['agri_max'] ?></td>
<td class='bg1'>상업</td>
<td class='comm-value'><?= $city['comm'] ?>/<?= $city['comm_max'] ?></td>
<td class='bg1'>치안</td>
<td class='secu-value'><?= $city['secu'] ?>/<?= $city['secu_max'] ?></td>
<td class='bg1'>수비</td>
<td class='def-value'><?= $city['def'] ?>/<?= $city['def_max'] ?></td>
<td class='bg1'>성벽</td>
<td class='wall-value'><?= $city['wall'] ?>/<?= $city['wall_max'] ?></td>
</tr>
<tr style='text-align:center;'>
<td class='bg1'>민심</td>
<td class='trust-value'><?= round($city['trust'], 1) ?></td>
<td class='bg1'>시세</td>
<td class='trade-value'><?= $city['trade'] ?>%</td>
<td class='bg1'>태수</td>
<td class='officer-4-value'><?= $officerName[4] ?></td>
<td class='bg1'>군사</td>
<td class='officer-3-value'><?= $officerName[3] ?></td>
<td class='bg1'>종사</td>
<td class='officer-2-value'><?= $officerName[2] ?></td>
</tr>
<tr>
<td style='text-align:center;' class='bg1'>장수</td>
<td colspan=9 class='city-generals'><?= key_exists($cityID, $cityGeneralList) ? join(', ', $cityGeneralList[$cityID]) : '-' ?></td>
</tr>
</table>
<?php } ?>
<table align=center width=1000 class='tb_layout bg0 anchor'> <table align=center width=1000 class='tb_layout bg0 anchor'>
<tr> <tr>
@@ -252,7 +268,7 @@ $sel = [$type => "selected"];
<td><?= banner() ?></td> <td><?= banner() ?></td>
</tr> </tr>
</table> </table>
<div id="helper_genlist" style="display:none;"></div>
</body> </body>
<div id="helper_genlist" style="display:none;"></div>
</html> </html>
+9 -11
View File
@@ -42,12 +42,14 @@ if ($gameStor->isunited) {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 세력장수</title> <title><?= UniqueConst::$serverName ?>: 세력장수</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common']) ?> <?= WebUtil::printDist('ts', ['common']) ?>
</head> </head>
@@ -95,7 +97,7 @@ if ($gameStor->isunited) {
7 => ['gold', true], 7 => ['gold', true],
8 => ['rice', true], 8 => ['rice', true],
9 => ['crew', true], 9 => ['crew', true],
10 => ['connect', true], 10 => ['refresh_score_total', true],
11 => ['personal', true], 11 => ['personal', true],
12 => ['special', true], 12 => ['special', true],
13 => ['special2', true], 13 => ['special2', true],
@@ -103,7 +105,9 @@ if ($gameStor->isunited) {
15 => ['npc', true], 15 => ['npc', true],
][$type]; ][$type];
$generalList = $db->query('SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,connect,gold,rice,crew,belong from general where nation = %i order by %b %l', $me['nation'], $orderKey, $orderDesc ? 'desc' : ''); $generalList = $db->query(
'SELECT owner,no,picture,imgsvr,npc,age,nation,special,special2,personal,name,injury,leadership,strength,intel,experience,dedication,officer_level,killturn,refresh_score_total,gold,rice,crew,belong
FROM `general` LEFT JOIN `general_access_log` ON general.no = general_access_log.general_id where nation = %i order by %b %l', $me['nation'], $orderKey, $orderDesc ? 'desc' : '');
echo " echo "
<table align=center class='tb_layout bg0'> <table align=center class='tb_layout bg0'>
@@ -146,13 +150,7 @@ if ($gameStor->isunited) {
$intel = "{$general['intel']}"; $intel = "{$general['intel']}";
} }
if ($general['npc'] >= 2) { $name = formatName($general['name'], $general['npc']);
$name = "<font color=cyan>{$general['name']}</font>";
} elseif ($general['npc'] == 1) {
$name = "<font color=skyblue>{$general['name']}</font>";
} else {
$name = "{$general['name']}";
}
if (key_exists($general['owner'], $ownerNameList)) { if (key_exists($general['owner'], $ownerNameList)) {
$name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>'; $name = $name . '<br><small>(' . $ownerNameList[$general['owner']] . ')</small>';
@@ -177,8 +175,8 @@ if ($gameStor->isunited) {
<td align=center>" . displayCharInfo($general['personal']) . "</td> <td align=center>" . displayCharInfo($general['personal']) . "</td>
<td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td> <td align=center>" . displaySpecialDomesticInfo($general['special']) . " / " . displaySpecialWarInfo($general['special2']) . "</td>
<td align=center>{$general['belong']}</td> <td align=center>{$general['belong']}</td>
<td align=center>{$general['connect']}"; <td align=center>". $general['refresh_score_total'] ?? 0;
echo "<br>(" . getConnect($general['connect']) . ")</td> echo "<br>(" . getRefreshScoreText($general['refresh_score_total'] ?? 0) . ")</td>
</tr>"; </tr>";
} }
echo " echo "
+2
View File
@@ -25,12 +25,14 @@ if ($nationID == 0) {
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 세력정보</title> <title><?= UniqueConst::$serverName ?>: 세력정보</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common']) ?> <?= WebUtil::printDist('ts', ['common']) ?>
</head> </head>
+82 -23
View File
@@ -2,11 +2,16 @@
namespace sammo; namespace sammo;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\TableName;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
$showDieImmediatelyBtn = false; $showDieOnPrestartBtn = false;
$availableDieImmediately = false; $showBuildNationCandidateBtn = false;
$availableDieOnPrestart = false;
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin()->setReadOnly();
@@ -19,7 +24,7 @@ $gameStor->cacheValues(['turntime', 'opentime', 'autorun_user', 'npcmode']);
increaseRefresh("내정보", 1); increaseRefresh("내정보", 1);
$me = General::createGeneralObjFromDB($generalID); $me = General::createObjFromDB($generalID, null, GeneralQueryMode::FullWithAccessLog);
$myset = $me->getVar('myset'); $myset = $me->getVar('myset');
if ($myset > 0) { if ($myset > 0) {
@@ -28,34 +33,63 @@ if ($myset > 0) {
$submit = 'hidden'; $submit = 'hidden';
} }
$targetTime = addTurn($me->getVar('lastrefresh'), $gameStor->turnterm, 2); $lastRefresh = $db->queryFirstField(
'SELECT %b FROM %b WHERE %b = %i',
GeneralAccessLogColumn::lastRefresh->value,
TableName::generalAccessLog->value,
GeneralAccessLogColumn::generalID->value,
$generalID
);
$targetTime = addTurn($lastRefresh, $gameStor->turnterm, GameConst::$minTurnDieOnPrestart);
if ($gameStor->turntime <= $gameStor->opentime) { if ($gameStor->turntime <= $gameStor->opentime) {
//서버 가오픈시 할 수 있는 행동 //서버 가오픈시 할 수 있는 행동
if ($me->getNPCType() == 0) { if ($me->getNPCType() == 0 && $me->getNationID() == 0) {
$showDieImmediatelyBtn = true; $showDieOnPrestartBtn = true;
if ($targetTime <= TimeUtil::now()) { if ($targetTime <= TimeUtil::now()) {
$availableDieImmediately = true; $availableDieOnPrestart = true;
} }
} }
if ($me->getNationID() == 0) {
$showBuildNationCandidateBtn = true;
}
} }
$use_treatment = $me->getAuxVar('use_treatment') ?? 10; $use_treatment = $me->getAuxVar('use_treatment') ?? 10;
$use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1; $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
$changeDefence999Train = -3;
$changeDefence999Atmos = -6;
$changeDefence999Train = $me->onCalcDomestic('changeDefenceTrain', "train999", $changeDefence999Train);
$changeDefence999Atmos = $me->onCalcDomestic('changeDefenceTrain', "atmos999", $changeDefence999Atmos);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=500" /> <meta name="viewport" content="width=500" />
<title><?= UniqueConst::$serverName ?>: 내정보</title> <title><?= UniqueConst::$serverName ?>: 내정보</title>
<script> <?= WebUtil::printStaticValues([
var availableDieImmediately = <?= $availableDieImmediately ? 'true' : 'false' ?>; 'availableDieOnPrestart' => $availableDieOnPrestart,
</script> 'staticValues' => [
'items' => Util::mapWithKey(fn (string $key, BaseItem $item) => [
'name' => $item->getName(),
'rawName' => $item->getRawName(),
'className' => $item->getRawClassName(),
'cost' => $item->getCost(),
'isBuyable' => $item->isBuyable(),
], $me->getItems())
]
]) ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['myPage']) ?> <?= WebUtil::printDist('ts', ['myPage']) ?>
</head> </head>
@@ -65,15 +99,15 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<div class="col">내 정 보<br><?= backButton() ?></div> <div class="col">내 정 보<br><?= backButton() ?></div>
</div> </div>
<div class="row gx-0"> <div class="row gx-0">
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row"> <div class="row">
<div class="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></div> <div class="col"><?php generalInfo($me); ?><?php generalInfo2($me); ?></div>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row"> <div class="row mx-0 gx-0">
<div class="col" style='padding-left:4ch;'> <div class="col" style='padding-left:2ch;'>
토너먼트 【 토너먼트 【
<input type=radio class='tnmt' name=tnmt value=0 <?= $me->getVar('tnmt') == 0 ? "checked" : ""; ?>>수동참여 <input type=radio class='tnmt' name=tnmt value=0 <?= $me->getVar('tnmt') == 0 ? "checked" : ""; ?>>수동참여
<input type=radio class='tnmt' name=tnmt value=1 <?= $me->getVar('tnmt') == 1 ? "checked" : ""; ?>>자동참여 <input type=radio class='tnmt' name=tnmt value=1 <?= $me->getVar('tnmt') == 1 ? "checked" : ""; ?>>자동참여
@@ -94,14 +128,17 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<option value=0 <?= (!$use_auto_nation_turn) ? "selected" : ""; ?>>허용 안함</option> <option value=0 <?= (!$use_auto_nation_turn) ? "selected" : ""; ?>>허용 안함</option>
</select>】<br> </select>】<br>
∞<span style='color:orange'>수뇌가 되었을 때 휴식 턴이어도 적당한 턴을 알아서 넣는 것을 허용합니다.</span><br><br> ∞<span style='color:orange'>수뇌가 되었을 때 휴식 턴이어도 적당한 턴을 알아서 넣는 것을 허용합니다.</span><br><br>
<?php else: ?> <?php else : ?>
<input type="hidden" id='use_auto_nation_turn' name='use_auto_nation_turn' value="1"/> <input type="hidden" id='use_auto_nation_turn' name='use_auto_nation_turn' value="1" />
<?php endif; ?> <?php endif; ?>
수비 【<select id='defence_train' name='defence_train'> 수비 【<select id='defence_train' name='defence_train'>
<?php foreach ([90, 80, 60, 40] as $targetDefenceTrain) : ?> <?php foreach ([90, 80, 60, 40] as $targetDefenceTrain) : ?>
<option value='<?= $targetDefenceTrain ?>' <?= $me->getVar('defence_train') == $targetDefenceTrain ? "selected" : ""; ?>><?= formatDefenceTrain($targetDefenceTrain) ?>(훈사<?= $targetDefenceTrain ?>)</option> <option value='<?= $targetDefenceTrain ?>' <?= $me->getVar('defence_train') == $targetDefenceTrain ? "selected" : ""; ?>><?= formatDefenceTrain($targetDefenceTrain) ?>(훈사<?= $targetDefenceTrain ?>)</option>
<?php endforeach; ?> <?php endforeach; ?>
<option value=999 <?= $me->getVar('defence_train') == 999 ? "selected" : ""; ?>><?= formatDefenceTrain(999) ?>[훈련, 사기 -3]</option> <option value=999 <?= $me->getVar('defence_train') == 999 ? "selected" : ""; ?>><?= formatDefenceTrain(999) ?>
<?php if($changeDefence999Train != 0 || $changeDefence999Train != 0):
?>[<?=$changeDefence999Train!=0?"훈련 {$changeDefence999Train},":''?><?=$changeDefence999Atmos!=0?"사기 {$changeDefence999Atmos}":''
?>]<?php endif?></option>
</select> </select>
】<br><br> 】<br><br>
<input type=<?= $submit ?> id='set_my_setting' name=btn style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px; value=설정저장><br> <input type=<?= $submit ?> id='set_my_setting' name=btn style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px; value=설정저장><br>
@@ -113,9 +150,19 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<!--빙의 해제용 삭턴 조절<br> <!--빙의 해제용 삭턴 조절<br>
<a href="b_myPage.php?detachNPC=1"><button type="button" style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>빙의 해체 요청</button></a>--> <a href="b_myPage.php?detachNPC=1"><button type="button" style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>빙의 해체 요청</button></a>-->
<?php if ($showDieImmediatelyBtn) : ?> <?php if ($showDieOnPrestartBtn) : ?>
가오픈 기간 내 장수 삭제 (<?= substr($targetTime, 0, 19) ?> 부터)<br> 가오픈 기간 내 장수 삭제 (<?= substr($targetTime, 0, 19) ?> 부터)<br>
<a href="c_die_immediately.php" id='die_immediately'><button type="button" style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>장수 삭제</button></a><br><br> <button type="button" id='dieOnPrestart' style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>장수 삭제</button><br><br>
<?php endif; ?>
<?php if ($showBuildNationCandidateBtn) : ?>
서버 개시 이전 거병(2턴부터 건국 가능)<br>
<button type="button" id='buildNationCandidate' style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>사전 거병</button><br><br>
<?php endif; ?>
<?php if (GameConst::$availableInstantAction['instantRetreat'] ?? false) : ?>
거리 3칸 이내 아국 도시로 즉시 이동<br>
<button type="button" id='instantRetreat' style=background-color:<?= GameConst::$basecolor2 ?>;color:white;width:160px;height:30px;font-size:14px;>접경 귀환</button><br><br>
<?php endif; ?> <?php endif; ?>
<?php if ($gameStor->npcmode == 2 && $me->getNPCType() == 0) : ?> <?php if ($gameStor->npcmode == 2 && $me->getNPCType() == 0) : ?>
@@ -138,6 +185,18 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
</div> </div>
<div class="row">
<div class="col">아이템 파기</div>
</div>
<div class="row mx-1">
<div class="btn-group" role="group">
<?php foreach ($me->getItems() as $itemKey => $item) : ?>
<button type="button" data-item-type='<?= $itemKey ?>' class="drop-item-btn btn btn-primary <?= $item->getName() == '-' ? 'disabled' : '' ?>"><?= $item->getName() ?></button>
<?php endforeach; ?>
</div>
</div>
<br> <br>
개인용 CSS<br> 개인용 CSS<br>
@@ -145,7 +204,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:skyblue'>개인 기록</h4> <h4 style='color:skyblue'>개인 기록</h4>
@@ -158,7 +217,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<button type="button" class="load_old_log btn btn-secondary" data-log_type="generalAction">이전 로그 불러오기</button> <button type="button" class="load_old_log btn btn-secondary" data-log_type="generalAction">이전 로그 불러오기</button>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:orange'>전투 기록</h4> <h4 style='color:orange'>전투 기록</h4>
@@ -172,7 +231,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:skyblue'>장수 열전</h4> <h4 style='color:skyblue'>장수 열전</h4>
@@ -182,7 +241,7 @@ $use_auto_nation_turn = $me->getAuxVar('use_auto_nation_turn') ?? 1;
<?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?> <?= formatHistoryToHTML(getGeneralHistoryLogAll($generalID)) ?>
</div> </div>
</div> </div>
<div class="col col-12 col-md-6"> <div class="col col-12 col-lg-6">
<div class="row gx-0"> <div class="row gx-0">
<div class="col bg1 text-center"> <div class="col bg1 text-center">
<h4 style='color:orange'>전투 결과</h4> <h4 style='color:orange'>전투 결과</h4>
+154 -167
View File
@@ -14,58 +14,106 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("토너먼트", 1); increaseRefresh("토너먼트", 1);
TurnExecutionHelper::executeAllCommand(); TurnExecutionHelper::executeAllCommand();
$me = $db->queryFirstRow('select no,tournament,con,turntime from general where owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no,tournament,refresh_score,turntime from `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id where owner=%i', $userID
);
$generalID = $me['no'];
$admin = $gameStor->getValues(['tournament', 'phase', 'turnterm', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']);
$turnTerm = $admin['turnterm'];
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_msg', 'tnmt_type', 'develcost', 'tnmt_trig']); $limitState = checkLimit($me['refresh_score']);
if ($limitState >= 2) {
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']); printLimitMsg($me['turntime']);
exit(); exit();
} }
switch ($admin['tnmt_type']) { switch ($admin['tnmt_type']) {
default: case convertTournamentType('전력전'):
throw new \RuntimeException('invalid tnmt_type'); $tnmt_type = "전력전";
case 0: $color = 'cyan';
$tnmt_type = "<font color=cyan>전력전</font>";
$tp = "total"; $tp = "total";
$tp2 = "종합"; $tp2 = "종합";
$tp3 = "total"; $tp3 = "total";
break; break;
case 1: case convertTournamentType('통솔전'):
$tnmt_type = "<font color=cyan>통솔전</font>"; $tnmt_type = "통솔전";
$color = 'cyan';
$tp = "leadership"; $tp = "leadership";
$tp2 = "통솔"; $tp2 = "통솔";
$tp3 = "leadership"; $tp3 = "leadership";
break; break;
case 2: case convertTournamentType('일기토'):
$tnmt_type = "<font color=cyan>일기토</font>"; $tnmt_type = "일기토";
$color = 'cyan';
$tp = "strength"; $tp = "strength";
$tp2 = "무력"; $tp2 = "무력";
$tp3 = "strength"; $tp3 = "strength";
break; break;
case 3: case convertTournamentType('설전'):
$tnmt_type = "<font color=cyan>설전</font>"; $tnmt_type = "설전";
$color = 'cyan';
$tp = "intel"; $tp = "intel";
$tp2 = "지력"; $tp2 = "지력";
$tp3 = "intel"; $tp3 = "intel";
break; break;
default:
throw new \RuntimeException('invalid tnmt_type');
} }
$bettingID = $gameStor->last_tournament_betting_id ?? 0;
if ($bettingID != 0) {
$betting = $bettingID != 0 ? new Betting($bettingID) : null;
$info = $betting->getInfo();
} else {
$info = getDummyBettingInfo($tnmt_type);
}
$myBet = [];
$globalBet = [];
if ($bettingID != 0) {
$betting = $bettingID != 0 ? new Betting($bettingID) : null;
$info = $betting->getInfo();
foreach ($db->queryAllLists(
'SELECT general_id, user_id, amount, betting_type FROM ng_betting WHERE betting_id = %i',
$bettingID
) as [$betGeneralID, $userID, $amount, $bettingTypeKey]) {
$bettingKey = Json::decode($bettingTypeKey)[0];
if ($betGeneralID == $generalID) {
$myBet[$bettingKey] = $amount;
}
if (key_exists($bettingKey, $globalBet)) {
$globalBet[$bettingKey] += $amount;
} else {
$globalBet[$bettingKey] = $amount;
}
}
} else {
$info = getDummyBettingInfo($tnmt_type);
}
$myBetTotal = array_sum($myBet);
$globalBetTotal = array_sum($globalBet);
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<?php if ($con == 1) { <?php if ($limitState == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^"); MessageBox("접속제한이 얼마 남지 않았습니다! 제한량이 모자라다면 참여를 해보세요^^");
} ?> } ?>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 토너먼트</title> <title><?= UniqueConst::$serverName ?>: 토너먼트</title>
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', 'common', true) ?> <?= WebUtil::printDist('ts', 'common', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" /> <link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
</head> </head>
@@ -77,128 +125,80 @@ switch ($admin['tnmt_type']) {
</tr> </tr>
</table> </table>
<table align=center class='tb_layout bg0'> <table align=center class='tb_layout bg0'>
<?php <?php if ($session->userGrade >= 5) : ?>
if ($session->userGrade >= 5) { <form method=post action=c_tournament.php>
$sel = []; <tr>
echo " <td colspan=8><input type=textarea size=150 style=color:white;background-color:black; name=msg><input type=submit name=btn value='메시지'></td>
<form method=post action=c_tournament.php> </tr>
<tr><td colspan=8><input type=textarea size=150 style=color:white;background-color:black; name=msg><input type=submit name=btn value='메시지'></td></tr> <tr>
<tr><td colspan=8> <td colspan=8>
<input type=button value='갱신' onclick='location.reload()'>"; <button type="button" class="btn btn-secondary" onclick='location.reload()'>갱신</button>
<?php if ($admin['tournament'] == 0) : ?>
<select name=trig size=1 style=color:white;background-color:black;>
<option style=color:white; value=0 <?= !$admin['tnmt_trig'] ? 'selected' : '' ?>>수동진행</option>
<option style=color:white; value=1 <?= $admin['tnmt_trig'] ? 'selected' : '' ?>>자동진행</option>
</select>
<input type=submit name=btn value='자동개최설정'>
<?php else : ?>
<input type=submit name=btn value='중단' onclick='return confirm("진짜 중단하시겠습니까?")'>
<?php endif; ?>
switch ($admin['tnmt_trig']) {
case 0:
$sel[0] = "selected";
break;
case 1:
$sel[1] = "selected";
break;
case 2:
$sel[2] = "selected";
break;
case 3:
$sel[3] = "selected";
break;
case 4:
$sel[4] = "selected";
break;
case 5:
$sel[5] = "selected";
break;
case 6:
$sel[6] = "selected";
break;
case 7:
$sel[7] = "selected";
break;
}
if ($admin['tournament'] == 0) { <?php switch ($admin['tournament']) {
?> case 1:
<select name=auto size=1 style=color:white;background-color:black;> echo "<input type=submit name=btn value='랜덤투입'>";
<option style=color:white; value=0>수동진행</option> echo "<input type=submit name=btn value='랜덤전부투입'>";
<option style=color:white; value=1>12분 05일</option> break;
<option style=color:white; value=2>07분 10시</option> case 2:
<option style=color:white; value=3>03분 04시</option> echo "<input type=submit name=btn value='예선'><input type=submit name=btn value='예선전부'>";
<option style=color:white; value=4>01분 82분</option> break;
<option style=color:white; value=5>30초 41분</option> case 3:
<option style=color:white; value=6>15초 21분</option> echo "<input type=submit name=btn value='추첨'><input type=submit name=btn value='추첨전부'>";
<option style=color:white; value=7>05초 07분</option> break;
</select> case 4:
<select name=type size=1 style=color:white;background-color:black;> echo "<input type=submit name=btn value='본선'><input type=submit name=btn value='본선전부'>";
<option style=color:white; value=0>전력전</option> break;
<option style=color:white; value=1>통솔전</option> case 5:
<option style=color:white; value=2>일기토</option> echo "<input type=submit name=btn value='배정'>";
<option style=color:white; value=3>설전</option> break;
</select> case 6:
<input type=submit name=btn value='개최'> echo "<input type=submit name=btn value='베팅마감'>";
<select name=trig size=1 style=color:white;background-color:black;> break;
<option style=color:white; value=0 <?= $sel[0] ?? '' ?>>수동진행</option> case 7:
<option style=color:white; value=1 <?= $sel[1] ?? '' ?>>12분 05일</option> echo "<input type=submit name=btn value='16강'>";
<option style=color:white; value=2 <?= $sel[2] ?? '' ?>>07분 10시</option> break;
<option style=color:white; value=3 <?= $sel[3] ?? '' ?>>03분 04시</option> case 8:
<option style=color:white; value=4 <?= $sel[4] ?? '' ?>>01분 82분</option> echo "<input type=submit name=btn value='8강'>";
<option style=color:white; value=5 <?= $sel[5] ?? '' ?>>30초 41분</option> break;
<option style=color:white; value=6 <?= $sel[6] ?? '' ?>>15초 21분</option> case 9:
<option style=color:white; value=7 <?= $sel[7] ?? '' ?>>05초 07분</option> echo "<input type=submit name=btn value='4강'>";
</select> break;
<input type=submit name=btn value='자동개최설정'> case 10:
<input type=submit name=btn value='포상'> echo "<input type=submit name=btn value='결승'>";
<input type=submit name=btn value='회수'> break;
<?php } ?>
} else {
echo "<input type=submit name=btn value='중단' onclick='return confirm(\"진짜 중단하시겠습니까?\")'>";
}
switch ($admin['tournament']) { </td>
case 1: </tr>
echo "<input type=submit name=btn value='랜덤투입'>"; </form>
echo "<input type=submit name=btn value='랜덤전부투입'>"; <?php elseif ($me['no'] > 0 && $me['tournament'] == 0 && $admin['tournament'] == 1) : ?>
break; <form method=post action=c_tournament.php>
case 2: <tr>
echo "<input type=submit name=btn value='예선'><input type=submit name=btn value='예선전부'>"; <td colspan=8><button type="button" class="btn btn-secondary" onclick='location.reload()'>갱신</button><button type="submit" class="btn btn-sammo-base2" onclick='return confirm("참가비 금<?= $admin['develcost'] ?>이 필요합니다. 참가하시겠습니까?")'>참가</button><input type='hidden' name='btn' value='참가'/></td>
break; </tr>
case 3: </form>
echo "<input type=submit name=btn value='추첨'><input type=submit name=btn value='추첨전부'>"; <?php else : ?>
break; <tr>
case 4: <td colspan=8><button type="button" class="btn btn-secondary" onclick='location.reload()'>갱신</button></td>
echo "<input type=submit name=btn value='본선'><input type=submit name=btn value='본선전부'>"; </tr>
break; <?php endif;
case 5:
echo "<input type=submit name=btn value='배정'>";
break;
case 6:
echo "<input type=submit name=btn value='베팅마감'>";
break;
case 7:
echo "<input type=submit name=btn value='16강'>";
break;
case 8:
echo "<input type=submit name=btn value='8강'>";
break;
case 9:
echo "<input type=submit name=btn value='4강'>";
break;
case 10:
echo "<input type=submit name=btn value='결승'>";
break;
}
echo "
</td></tr>
</form>";
} elseif ($me['no'] > 0 && $me['tournament'] == 0 && $admin['tournament'] == 1) {
echo "<form method=post action=c_tournament.php><tr><td colspan=8><input type=button value='갱신' onclick='location.reload()'><input type=submit name=btn value='참가' onclick='return confirm(\"참가비 금{$admin['develcost']}이 필요합니다. 참가하시겠습니까?\")'></td></tr></form>";
} else {
echo "<tr><td colspan=8><input type=button value='갱신' onclick='location.reload()'></td></tr>";
}
$str1 = getTournament($admin['tournament']); $str1 = getTournament($admin['tournament']);
$str2 = getTournamentTime(); $str2 = getTournamentTime();
if ($str2) { if ($str2) {
$str2 = ', ' . $str2; $str2 = ', ' . $str2;
} }
$str3 = getTournamentTerm(); $str3 = getTournamentTermText($turnTerm);
if ($str3) { if ($str3) {
$str3 = ', ' . $str3; $str3 = ', ' . $str3;
} }
@@ -209,7 +209,7 @@ switch ($admin['tnmt_type']) {
</tr> </tr>
<tr> <tr>
<td colspan=8 align=center> <td colspan=8 align=center>
<font color=white size=6><?= $tnmt_type ?> (<?= $str1 . $str2 . $str3 ?>)</font> <font color=white size=6><span style="color:<?= $color ?>"><?= $tnmt_type ?></span> (<?= $str1 . $str2 . $str3 ?>)</font>
</td> </td>
</tr> </tr>
<tr> <tr>
@@ -240,11 +240,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
echo "<td colspan=16>{$general['name']}</td>"; echo "<td colspan=16>{$general['name']}</td>";
} }
@@ -270,11 +266,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -316,11 +308,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -363,11 +351,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -409,11 +393,7 @@ switch ($admin['tnmt_type']) {
if ($general['name'] == "") { if ($general['name'] == "") {
$general['name'] = "-"; $general['name'] = "-";
} }
if ($general['npc'] >= 2) { $general['name'] = formatName($general['name'], $general['npc']);
$general['name'] = "<font color=cyan>" . $general['name'] . "</font>";
} elseif ($general['npc'] == 1) {
$general['name'] = "<font color=skyblue>" . $general['name'] . "</font>";
}
if ($general['win'] > 0) { if ($general['win'] > 0) {
$line[$i] = "<font color=red>"; $line[$i] = "<font color=red>";
$cent[intdiv($i, 2)] = "<font color=red>"; $cent[intdiv($i, 2)] = "<font color=red>";
@@ -438,24 +418,31 @@ switch ($admin['tnmt_type']) {
echo " echo "
</tr>"; </tr>";
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0') ?? [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,];
$globalBet = array_splice($globalBet, -16);
$globalBetTotal = array_sum($globalBet);
$admin = $gameStor->getValues(['tournament', 'phase']); $admin = $gameStor->getValues(['tournament', 'phase']);
$bet = []; $bet = [];
for ($i = 0; $i < 16; $i++) { $gold = [];
if ($globalBet[$i] == 0) { $keyMap = [];
$bet[$i] = '∞'; foreach ($info->candidates as $key => $candidate) {
continue; $keyMap[$candidate->aux['idx']] = $key;
}
foreach ($globalBet as $key => $amount) {
if ($amount == 0) {
$bet[$key] = "∞";
$gold[$key] = 0;
} else {
$rewardRatio = round($globalBetTotal / $amount, 2);
$bet[$key] = $rewardRatio;
$gold[$key] = $rewardRatio * ($myBet[$key] ?? 0);
} }
$bet[$i] = round($globalBetTotal / $globalBet[$i], 2);
} }
echo " echo "
<tr align=center>"; <tr align=center>";
for ($i = 0; $i < 16; $i++) { foreach (range(0, 15) as $i) {
echo "<td><font color=skyblue>{$bet[$i]}</font></td>"; $amount = $bet[$keyMap[$i] ?? -1] ?? 0;
echo "<td><font color=skyblue>{$amount}</font></td>";
} }
echo " echo "
@@ -489,7 +476,7 @@ switch ($admin['tnmt_type']) {
printRow($k, $general['npc'], $general['name'], $general[$tp], $general['game'], $general['win'], $general['draw'], $general['lose'], $general['gd'], $general['gl'], $general['prmt']); printRow($k, $general['npc'], $general['name'], $general[$tp], $general['game'], $general['win'], $general['draw'], $general['lose'], $general['gd'], $general['gl'], $general['prmt']);
} }
foreach (Util::range(count($generalList), 4) as $idx) { foreach (Util::range(count($generalList), 4) as $idx) {
printRow($idx, '', '', '', '', '', '', '', '', '', ''); printRow($idx, 0, '', '', '', '', '', '', '', '', '');
} }
echo " echo "
</table> </table>
@@ -516,7 +503,7 @@ switch ($admin['tnmt_type']) {
printRow($k, $general['npc'], $general['name'], $general[$tp], $general['game'], $general['win'], $general['draw'], $general['lose'], $general['gd'], $general['gl'], $general['prmt']); printRow($k, $general['npc'], $general['name'], $general[$tp], $general['game'], $general['win'], $general['draw'], $general['lose'], $general['gd'], $general['gl'], $general['prmt']);
} }
foreach (Util::range(count($generalList), 8) as $idx) { foreach (Util::range(count($generalList), 8) as $idx) {
printRow($idx, '', '', '', '', '', '', '', '', '', ''); printRow($idx, 0, '', '', '', '', '', '', '', '', '');
} }
echo " echo "
</table> </table>
-230
View File
@@ -1,230 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
increaseRefresh("부대편성", 1);
$me = $db->queryFirstRow('SELECT no,nation,troop FROM general WHERE owner=%i', $userID);
$troops = [];
foreach ($db->query('SELECT troop_leader,name FROM troop WHERE nation = %i', $me['nation']) as $rawTroop) {
$troops[$rawTroop['troop_leader']] = [
'name' => $rawTroop['name'],
'users' => []
];
}
foreach ($db->query(
'SELECT no,name,turntime,troop,city FROM general WHERE troop!=0 AND nation = %i ORDER BY turntime ASC',
$me['nation']
) as $general) {
if (!key_exists($general['troop'], $troops)) {
trigger_error("올바르지 않은 부대 소속 {$general['no']}, {$general['name']} : {$general['troop']}");
continue;
}
$general['cityText'] = CityConst::byID($general['city'])->name;
$troops[$general['troop']]['users'][] = $general;
}
if ($troops) {
$troopLeaders = $db->query(
'SELECT no,name,picture,imgsvr,turntime,city,troop FROM general WHERE no IN %li',
array_keys($troops)
);
$generalTurnList = [];
foreach ($db->queryAllLists(
'SELECT general_id, turn_idx, brief FROM general_turn WHERE general_id IN %li AND turn_idx < 5 ORDER BY general_id ASC, turn_idx ASC',
array_column($troopLeaders, 'no')
) as [$generalID, $turnIdx, $brief]) {
if (!key_exists($generalID, $generalTurnList)) {
$generalTurnList[$generalID] = [];
}
$generalTurnList[$generalID][$turnIdx] = $brief;
}
foreach ($troopLeaders as $troopLeader) {
$imageTemp = GetImageURL($troopLeader['imgsvr']);
$troopLeader['pictureFullPath'] = "$imageTemp/{$troopLeader['picture']}";
$troopLeader['cityText'] = CityConst::byID($troopLeader['city'])->name;
$turnText = [];
foreach ($generalTurnList[$troopLeader['no']] as $rawTurnIdx => $brief) {
if ($brief != '집합') {
$brief = '~';
}
$turnIdx = $rawTurnIdx + 1;
$turnText[] = "{$turnIdx} : {$brief}";
}
$troopLeader['turnText'] = join('<br>', $turnText);
$troops[$troopLeader['troop']]['leader'] = $troopLeader;
}
}
uasort($troops, function ($lhs, $rhs) {
return $lhs['leader']['turntime'] <=> $rhs['leader']['turntime'];
})
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" />
<title><?= UniqueConst::$serverName ?>: 부대편성</title>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('ts', ['common', 'troop'], true) ?>
</head>
<body>
<div style="width:1000px;margin:auto;">
<table width=1000 class='tb_layout bg0'>
<tr>
<td>부 대 편 성<br><?= backButton() ?></td>
</tr>
</table>
<table id="troop_list" class='tb_layout bg0'>
<thead>
<tr>
<td width=64 class='bg1 center'>선 택</td>
<td width=130 class='bg1 center'>부 대 정 보</td>
<td width=100 class='bg1 center'>부 대 장</td>
<td width=576 class='bg1 center' style=table-layout:fixed;word-break:break-all;>장 수</td>
<td width=130 class='bg1 center' style=table-layout:fixed;word-break:break-all;>부대장행동</td>
</tr>
</thead>
<tfoot>
<tr>
<td colspan='5'>
<?php if (!$troops) : ?>
<?php elseif ($me['troop'] == 0) : ?>
<input type=button id='btnJoinTroop' value='부 대 가 입'>
<?php else : ?>
<input type=button id="btnLeaveTroop" value='부 대 탈 퇴'>
<?php endif; ?>
</td>
</tr>
</tfoot>
<tbody>
<?php
foreach ($troops as $troopNo => $troop) {
$troopLeader = $troop['leader'];
$genlistText = [];
$cityText = $troopLeader['cityText'];
$cityID = $troopLeader['city'];
$leaderID = $troopLeader['no'];
foreach ($troop['users'] as $troopUser) {
$spanClass = 'troopUser';
if ($troopUser['city'] !== $cityID) {
$spanClass .= ' diffCity';
}
if ($troopUser['no'] == $leaderID) {
$spanClass .= ' leader';
}
$genlistText[] = "<span class='$spanClass' data-general-id='{$troopUser['no']}'
><span class='generalName'>{$troopUser['name']}</span><span class='cityText'>【{$troopUser['cityText']}】</span
></span>";
}
$genlistText = sprintf('%s (%d명)', join(', ', $genlistText), count($genlistText)); ?>
<?php if ($me['troop'] == 0) : ?>
<tr>
<td align=center rowspan=2><input type='radio' class='troopId' name='troop' value='<?= $troopNo ?>'></td>
<td align=center><?= $troop['name'] ?><br>【 <?= $cityText ?> 】</td>
<td height=64 class='generalIcon' style='background:no-repeat center url("<?= $troopLeader['pictureFullPath'] ?>");background-size:64px;'>&nbsp;</td>
<td rowspan=2 width=62><?= $genlistText ?></td>
<td rowspan=2><?= $troopLeader['turnText'] ?></td>
</tr>
<tr>
<td align=center>
<font size=2>【턴】 <?= substr($troopLeader['turntime'], 14, 5) ?></font>
</td>
<td align=center>
<font size=1><?= $troopLeader['name'] ?></font>
</td>
</tr>
<tr>
<td colspan=5>
<?php else : ?>
<tr>
<td align=center rowspan=2>&nbsp;</td>
<td align=center><?= $troop['name'] ?><br>【 <?= $cityText ?> 】</td>
<td height=64 class='generalIcon' style='background:no-repeat center url("<?= $troopLeader['pictureFullPath'] ?>");background-size:64px;'>&nbsp;</td>
<td rowspan=2 width=62><?= $genlistText ?></td>
<td rowspan=2>
<?php if ($me['no'] == $troopLeader['no']) : ?>
<select id='genNo' name=gen size=3 style=color:white;background-color:black;font-size:14px;width:128px;>";
<?php foreach ($troop['users'] as $troopUser) : ?>
<?php if ($troopUser['no'] == $me['no']) {
continue;
} ?>
<option value='<?= $troopUser['no'] ?>'><?= $troopUser['name'] ?></option>
<?php endforeach; ?>
</select><br>
<input type=button id='btnKickTroop' value='부 대 추 방' style=width:130px;height:25px;>
<?php else : ?>
<?= $troopLeader['turnText'] ?>
<?php endif; ?>
</td>
</tr>
<tr>
<td align=center>
<font size=2>【턴】 <?= substr($troopLeader['turntime'], 14, 5) ?></font>
</td>
<td align=center>
<font size=1><?= $troopLeader['name'] ?></font>
</td>
</tr>
<tr>
<td colspan=5></td>
</tr>
<?php endif;
} //foreach ($troops as $troopNo=>$troop) {
?>
</tbody>
</table>
<br>
<table width=1000 class='tb_layout bg0'>
<tr>
<td width=80 class='bg1'>부 대 명</td>
<td width=130><input type=text style=color:white;background-color:black; size=18 maxlength=18 id='nameplate'></td>
<?php if ($me['troop'] == 0) : ?>
<td><input type=button id='btnCreateTroop' value='부 대 창 설'></td>
<?php else : ?>
<td><input type=button id='btnChangeTroopName' value='부 대 변 경'></td>
<?php endif; ?>
</tr>
</table>
<table width=1000 class='tb_layout bg0'>
<tr>
<td><?= backButton() ?></td>
</tr>
<tr>
<td><?= banner() ?> </td>
</tr>
</table>
</div>
</body>
</html>
+32 -3
View File
@@ -43,6 +43,7 @@ if ($nationID) {
<head> <head>
<title><?= UniqueConst::$serverName ?>: 전투 시뮬레이터</title> <title><?= UniqueConst::$serverName ?>: 전투 시뮬레이터</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1100" /> <meta name="viewport" content="width=1100" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -54,6 +55,7 @@ if ($nationID) {
var city = <?= Json::encode($city) ?>; var city = <?= Json::encode($city) ?>;
var nation = <?= Json::encode($nation) ?>; var nation = <?= Json::encode($nation) ?>;
</script> </script>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'battle_simulator']) ?> <?= WebUtil::printDist('ts', ['common', 'battle_simulator']) ?>
</head> </head>
@@ -64,8 +66,8 @@ if ($nationID) {
전역 설정 전역 설정
</div> </div>
<div class="card-body dragpad_battle"> <div class="card-body dragpad_battle">
<div class="row"> <div class="row gx-0">
<div class="col-sm-6"> <div class="col-sm-4">
<div class="input-group"> <div class="input-group">
<input type="number" class="form-control" aria-describedby="text_year" value="<?= $startYear ?>" disabled> <input type="number" class="form-control" aria-describedby="text_year" value="<?= $startYear ?>" disabled>
<div class="input-group-text"> 년 시작 </div> <div class="input-group-text"> 년 시작 </div>
@@ -75,9 +77,13 @@ if ($nationID) {
<div class="input-group-text"> 월 </div> <div class="input-group-text"> 월 </div>
</div> </div>
</div> </div>
<div class="col-sm-6"> <div class="col-sm-5 px-2">
<div class="btn-toolbar" role="toolbar"> <div class="btn-toolbar" role="toolbar">
<div class="input-group me-2" role="group"> <div class="input-group me-2" role="group">
<div class="input-group-text">
시드
</div>
<input type="text" class="form-control" id="seed" aria-describedby="text_seed">
<div class="input-group-text"> <div class="input-group-text">
반복 횟수 반복 횟수
</div> </div>
@@ -86,6 +92,10 @@ if ($nationID) {
<option value="1000">1000회 (요약 표기)</option> <option value="1000">1000회 (요약 표기)</option>
</select> </select>
</div> </div>
</div>
</div>
<div class="col-sm-3">
<div class="btn-toolbar" role="toolbar">
<div class="btn-group me-2" role="group"> <div class="btn-group me-2" role="group">
<button type="button" class="btn btn-danger btn-begin_battle">전투</button> <button type="button" class="btn btn-danger btn-begin_battle">전투</button>
</div> </div>
@@ -425,6 +435,25 @@ if ($nationID) {
</div> </div>
<input type="number" class="form-control form_killcrew" value="0" step="1"> <input type="number" class="form-control form_killcrew" value="0" step="1">
</div> </div>
<div class="input-group mb-0">
<div class="input-group-text">자신</div>
<div class="input-group-text">회피 확률</div>
<input type="number" class="form-control form_war_avoid_ratio" value="0" step="1" min="0" max="5">
<div class="input-group-text">필살 확률</div>
<input type="number" class="form-control form_war_critical_ratio" value="0" step="1" min="0" max="5">
<div class="input-group-text">계략 시도 확률</div>
<input type="number" class="form-control form_war_magic_trial_prob" value="0" step="1" min="0" max="5">
</div>
<div class="input-group mb-1">
<div class="input-group-text">상대</div>
<div class="input-group-text">회피 확률</div>
<input type="number" class="form-control form_oppose_war_avoid_ratio" value="0" step="1" min="0" max="5">
<div class="input-group-text">필살 확률</div>
<input type="number" class="form-control form_oppose_war_critical_ratio" value="0" step="1" min="0" max="5">
<div class="input-group-text">계략 시도 확률</div>
<input type="number" class="form-control form_oppose_war_magic_trial_prob" value="0" step="1" min="0" max="5">
</div>
</div> </div>
</div> </div>
-247
View File
@@ -1,247 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$v = new Validator($_POST + $_GET);
$v->rule('integer', [
'amount',
'cost',
'topv',
'value',
'term',
'sel'
]);
$btn = Util::getPost('btn');
$amount = Util::getPost('amount', 'int');
$cost = Util::getPost('cost', 'int');
$topv = Util::getPost('topv', 'int');
$value = Util::getPost('value', 'int');
$term = Util::getPost('term', 'int');
$sel = Util::getPost('sel', 'int');
$msg = '';
$msg2 = '';
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("입찰", 1);
$turnterm = $gameStor->turnterm;
$me = $db->queryFirstRow('SELECT no,name,gold,rice,special from general where owner=%i', $userID);
$tradeCount = $db->queryFirstField('SELECT count(no) FROM auction WHERE no1=%i', $me['no']);
$bidCount = $db->queryFirstField('SELECT count(no) FROM auction WHERE no2=%i', $me['no']);
$btCount = $tradeCount + $bidCount;
$unit = $turnterm * 60;
$amount = Util::round($amount, -1);
$cost = Util::round($cost, -1);
$topv = Util::round($topv, -1);
$value = Util::round($value, -1);
if ($term > 24) {
$term = 24;
}
$valid = 1;
if ($session->userGrade >= 5 || $btCount < 1) {
} else {
$msg = "ㆍ<span class='ev_warning'>더이상 등록할 수 없습니다.</span>";
$msg2 = "ㆍ<span class='ev_warning'>더이상 등록할 수 없습니다.</span>";
$valid = 0;
$btn = "hidden";
}
if ($btn == "판매") {
if ($term < 0 || $term > 24) {
$msg = "ㆍ<span class='ev_warning'>종료기한은 1 ~ 24 턴 이어야 합니다.</span>";
$valid = 0;
}
if ($amount < 100 || $amount > 10000) {
$msg = "ㆍ<span class='ev_warning'>거래량은 100 ~ 10000 이어야 합니다.</span>";
$valid = 0;
}
if ($cost > $amount * 2 || $cost * 2 < $amount) {
$msg = "ㆍ<span class='ev_warning'>시작판매가는 50% ~ 200% 이어야 합니다.</span>";
$valid = 0;
}
if ($topv * 10 < $amount * 11 || $topv > $amount * 2) {
$msg = "ㆍ<span class='ev_warning'>즉시판매가는 110% ~ 200% 이어야 합니다.</span>";
$valid = 0;
}
if ($topv * 10 < $cost * 11) {
$msg = "ㆍ<span class='ev_warning'>즉시판매가는 시작판매가의 110% 이상이어야 합니다.</span>";
$valid = 0;
}
if ($amount > $me['rice'] - GameConst::$defaultRice) {
$msg = "ㆍ<span class='ev_warning'>기본 군량 ".GameConst::$defaultRice."은 거래할 수 없습니다.</span>";
$valid = 0;
}
if ($valid == 1) {
$msg = "ㆍ<span class='ev_success'>등록 성공.</span>";
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit * $term);
$db->insert('auction', [
'type'=>0,
'no1'=>$me['no'],
'name1'=>$me['name'],
'amount'=>$amount,
'cost'=>$cost,
'value'=>$cost,
'topv'=>$topv,
'expire'=>$date
]);
}
} elseif ($btn == "구매시도") {
$auction = $db->queryFirstRow('SELECT no2,value,topv,expire,amount FROM auction WHERE no=%i LIMIT 1', $sel);
if ($value == $auction['topv']) {
$valid = 2;
}
if (!$auction) {
$msg = "ㆍ<span class='ev_warning'>종료된 거래입니다.</span>";
$valid = 0;
}
if ($auction['no2'] > 0 && $value <= $auction['value']) {
$msg = "ㆍ<span class='ev_warning'>현재판매가보다 높게 입찰해야 합니다.</span>";
$valid = 0;
}
if ($value < $auction['value']) {
$msg = "ㆍ<span class='ev_warning'>현재판매가보다 높게 입찰해야 합니다.</span>";
$valid = 0;
}
if ($value > $auction['topv']) {
$msg = "ㆍ<span class='ev_warning'>즉시판매가보다 높을 수 없습니다.</span>";
$valid = 0;
}
if ($value > $me['gold'] - GameConst::$defaultGold) {
$msg = "ㆍ<span class='ev_warning'>기본 자금 ".GameConst::$defaultGold."은 거래할 수 없습니다.</span>";
$valid = 0;
}
if ($valid == 1) {
$msg = "ㆍ<span class='ev_success'>입찰 성공.</span> 거래완료는 빨라도 현재로부터 1턴 뒤입니다.";
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit);
if ($auction['expire'] > $date) {
$date = $auction['expire'];
}
$db->update('auction', [
'value'=>$value,
'no2'=>$me['no'],
'name2'=>$me['name'],
'expire'=>$date,
], 'no=%i', $sel);
} elseif ($valid == 2) {
$msg = "ㆍ<span class='ev_success'>즉시판매 성공.</span> 거래완료는 빨라도 현재로부터 1턴 뒤입니다.";
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit);
$db->update('auction', [
'value'=>$value,
'no2'=>$me['no'],
'name2'=>$me['name'],
'expire'=>$date,
], 'no=%i', $sel);
}
} elseif ($btn == "구매") {
if ($term < 0 || $term > 24) {
$msg2 = "ㆍ<span class='ev_warning'>종료기한은 1 ~ 24 턴 이어야 합니다.</span>";
$valid = 0;
}
if ($amount < 100 || $amount > 10000) {
$msg2 = "ㆍ<span class='ev_warning'>거래량은 100 ~ 10000 이어야 합니다.</span>";
$valid = 0;
}
if ($cost > $amount * 2 || $cost * 2 < $amount) {
$msg2 = "ㆍ<span class='ev_warning'>시작구매가는 50% ~ 200% 이어야 합니다.</span>";
$valid = 0;
}
if ($topv < $amount * 0.5 || $topv > $amount * 0.9) {
$msg2 = "ㆍ<span class='ev_warning'>즉시구매가는 50% ~ 90% 이어야 합니다.</span>";
$valid = 0;
}
if ($topv > $cost * 0.9) {
$msg2 = "ㆍ<span class='ev_warning'>즉시구매가는 시작구매가의 90% 이하이어야 합니다.</span>";
$valid = 0;
}
if ($cost > $me['gold'] - GameConst::$defaultGold) {
$msg2 = "ㆍ<span class='ev_warning'>기본 자금 ".GameConst::$defaultGold."은 거래할 수 없습니다.</span>";
$valid = 0;
}
if ($valid == 1) {
$msg2 = "ㆍ<span class='ev_success'>등록 성공.</span>";
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit * $term);
$db->insert('auction', [
'type'=>1,
'no1'=>$me['no'],
'name1'=>$me['name'],
'amount'=>$amount,
'cost'=>$cost,
'value'=>$cost,
'topv'=>$topv,
'expire'=>$date
]);
}
} elseif ($btn == "판매시도") {
$auction = $db->queryFirstRow('SELECT no2,value,topv,expire,amount FROM auction WHERE no=%i LIMIT 1', $sel);
if ($value == $auction['topv']) {
$valid = 2;
}
if (!$auction) {
$msg2 = "ㆍ<span class='ev_warning'>종료된 거래입니다.</span>";
$valid = 0;
}
if ($auction['no2'] > 0 && $value >= $auction['value']) {
$msg2 = "ㆍ<span class='ev_warning'>현재구매가보다 낮게 입찰해야 합니다.</span>";
$valid = 0;
}
if ($value > $auction['value']) {
$msg2 = "ㆍ<span class='ev_warning'>현재구매가보다 낮게 입찰해야 합니다.</span>";
$valid = 0;
}
if ($value < $auction['topv']) {
$msg2 = "ㆍ<span class='ev_warning'>즉시구매가보다 낮을 수 없습니다.</span>";
$valid = 0;
}
if ($value > $me['rice'] - GameConst::$defaultRice) {
$msg2 = "ㆍ<span class='ev_warning'>기본 군량 ".GameConst::$defaultRice."은 거래할 수 없습니다.</span>";
$valid = 0;
}
if ($valid == 1) {
$msg2 = "ㆍ<span class='ev_success'>입찰 성공.</span> 거래완료는 빨라도 현재로부터 1턴 뒤입니다.";
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit);
if ($auction['expire'] > $date) {
$date = $auction['expire'];
}
$db->update('auction', [
'value'=>$value,
'no2'=>$me['no'],
'name2'=>$me['name'],
'expire'=>$date,
], 'no=%i', $sel);
} elseif ($valid == 2) {
$msg2 = "ㆍ<span class='ev_success'>즉시구매 성공.</span> 거래완료는 빨라도 현재로부터 1턴 뒤입니다.";
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit);
$db->update('auction', [
'value'=>$value,
'no2'=>$me['no'],
'name2'=>$me['name'],
'expire'=>$date,
], 'no=%i', $sel);
}
}
Submit("b_auction.php", $msg, $msg2);
+16 -6
View File
@@ -15,7 +15,7 @@ $sel = Util::getPost('sel', 'int');
$trig = Util::getPost('trig', 'int'); $trig = Util::getPost('trig', 'int');
//로그인 검사 //로그인 검사
$session = Session::requireGameLogin()->setReadOnly(); $session = Session::requireGameLogin();
$userID = Session::getUserID(); $userID = Session::getUserID();
$db = DB::db(); $db = DB::db();
@@ -24,7 +24,11 @@ $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['tournament','phase','tnmt_type','develcost']); $admin = $gameStor->getValues(['tournament','phase','tnmt_type','develcost']);
$me = $db->queryFirstRow('SELECT no,name,tournament from general where owner=%i',$userID); $me = $db->queryFirstRow('SELECT no,name,tournament from general where owner=%i',$userID);
if(!$me){
$session->logoutGame();
header('location:b_tournament.php');
exit(1);
}
switch($admin['tnmt_type']) { switch($admin['tnmt_type']) {
case 0: $tp = "total"; $tp2 = "전력전"; $tp3 = "leadership+strength+intel"; break; case 0: $tp = "total"; $tp2 = "전력전"; $tp3 = "leadership+strength+intel"; break;
case 1: $tp = "leadership"; $tp2 = "통솔전"; $tp3 = "leadership"; break; case 1: $tp = "leadership"; $tp2 = "통솔전"; $tp3 = "leadership"; break;
@@ -40,6 +44,10 @@ if($btn == '참가') {
} }
$general = $db->queryFirstRow('SELECT no,name,npc,leadership,strength,intel,explevel,gold,horse,weapon,book FROM general WHERE `no`=%i', $me['no']); $general = $db->queryFirstRow('SELECT no,name,npc,leadership,strength,intel,explevel,gold,horse,weapon,book FROM general WHERE `no`=%i', $me['no']);
if(!$general){
header('location:b_tournament.php');
exit(1);
}
//{$admin['develcost']}원 참가비 //{$admin['develcost']}원 참가비
if($general['gold'] < $admin['develcost']) { if($general['gold'] < $admin['develcost']) {
@@ -90,8 +98,8 @@ if($btn == '참가') {
], 'no=%i', $general['no']); ], 'no=%i', $general['no']);
} }
$grpCount = $db->queryFirstField('SELECT count(*) FROM tournament where grp<10 GROUP BY grp HAVING count(*)=8'); $grpCount = $db->queryFirstColumn('SELECT count(grp) FROM tournament where grp<10 GROUP BY grp;');
if($grpCount >= 8) { if(min($grpCount) >= 8) {
$gameStor->tournament = 2; $gameStor->tournament = 2;
$gameStor->phase = 0; $gameStor->phase = 0;
} }
@@ -105,11 +113,11 @@ if($session->userGrade < 5) {
} }
if($btn == "자동개최설정") { if($btn == "자동개최설정") {
$gameStor->tnmt_trig = $trig; $gameStor->tnmt_trig = !!$trig;
} elseif($btn == "개최") { } elseif($btn == "개최") {
startTournament($auto, $type); startTournament($auto, $type);
} elseif($btn == "중단") { } elseif($btn == "중단") {
$gameStor->tnmt_auto = 0; $gameStor->tnmt_auto = false;
$gameStor->tournament = 0; $gameStor->tournament = 0;
$gameStor->phase = 0; $gameStor->phase = 0;
} elseif($btn == "랜덤투입") { } elseif($btn == "랜덤투입") {
@@ -217,6 +225,8 @@ if($btn == "자동개최설정") {
finallyAll($admin['tnmt_type'], $admin['tournament'], $admin['phase']); finallyAll($admin['tnmt_type'], $admin['tournament'], $admin['phase']);
} elseif($btn == "배정") { } elseif($btn == "배정") {
final16set(); final16set();
$phase = 0;
startBetting($admin['tnmt_type'], 720);
} elseif($btn == "베팅마감") { } elseif($btn == "베팅마감") {
$dt = date("Y-m-d H:i:s", time() + 60); $dt = date("Y-m-d H:i:s", time() + 60);
$gameStor->tournament=7; $gameStor->tournament=7;
-91
View File
@@ -1,91 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
$btn = Util::getPost('btn');
$sel = Util::getPost('sel', 'int');
$comment = Util::getPost('comment');
$title = Util::getPost('title');
$str = Util::getPost('str');
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$isVoteAdmin = in_array('vote', $session->acl[DB::prefix()]??[]);
$isVoteAdmin = $isVoteAdmin || $session->userGrade >= 5;
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['develcost', 'cost', 'vote_title', 'vote', 'votecomment']);
$generalID = Session::getGeneralID();
$general = General::createGeneralObjFromDB($generalID, ['vote','horse','weapon','book','item','npc','imgsvr','picture','aux'], 2);
if($btn == "투표" && $general->getVar('vote') == 0 && $sel > 0) {
$develcost = $admin['develcost'] * 5;
$db->update('general', [
'gold'=>$db->sqleval('gold + %i', $develcost),
'vote'=>$sel
], 'owner=%i', $userID);
if(tryUniqueItemLottery($general, '설문조사')){
$general->applyDB($db);
}
}
else if($btn == "댓글" && trim($comment) != "") {
$comment = StringUtil::neutralize($comment);
$nation = $general->getStaticNation();
if(!$admin['votecomment']){
$admin['votecomment'] = [];
}
$admin['votecomment'][] = [$nation['name'],$general->getName(),$comment];
$gameStor->votecomment = $admin['votecomment'];
}
if(!$isVoteAdmin){
header('location:a_vote.php', true, 303);
die();
}
if($btn == "수정") {
if($title != "") {
$gameStor->vote_title = WebUtil::htmlPurify($title);
}
} elseif($btn == "추가") {
if($str != "") {
if(!$admin['vote']){
$admin['vote'] = [];
}
$admin['vote'][] = WebUtil::htmlPurify($str);
$gameStor->vote=$admin['vote'];
}
} elseif($btn == "리셋") {
$gameStor->voteopen=1;
$gameStor->vote=['-'];
$gameStor->vote_title = '-';
$gameStor->votecomment=[];
$db->update('general', [
'vote'=>0
], true);
} elseif($btn == "알림") {
$db->update('general', [
'newvote'=>1
], 'vote=0');
} elseif($btn == "숨김") {
$gameStor->voteopen = 0;
} elseif($btn == "전체통계만") {
$gameStor->voteopen = 1;
} elseif($btn == "전부") {
$gameStor->voteopen = 2;
}
header('location:a_vote.php', true, 303);
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 582 B

+4 -6
View File
@@ -1,5 +1,3 @@
@charset "UTF-8";
.world_map { .world_map {
width: 700px; width: 700px;
background: black; background: black;
@@ -69,11 +67,11 @@
} }
.map_body .map_toggle_cityname::after { .map_body .map_toggle_cityname::after {
content: "끄기" content: " 끄기"
} }
.map_body .map_toggle_cityname.active::after { .map_body .map_toggle_cityname.active::after {
content: "켜기" content: " 켜기"
} }
.map_body .map_toggle_single_tap { .map_body .map_toggle_single_tap {
@@ -81,11 +79,11 @@
} }
.map_body .map_toggle_single_tap::after { .map_body .map_toggle_single_tap::after {
content: "끄기" content: " 끄기"
} }
.map_body .map_toggle_single_tap.active::after { .map_body .map_toggle_single_tap.active::after {
content: "켜기" content: " 켜기"
} }
.world_map .city_tooltip { .world_map .city_tooltip {
+2 -7
View File
@@ -52,8 +52,8 @@ class DB
/** /**
* DB 객체 생성 * DB 객체 생성
* *
* @return \MeekroDB * @return \MeekroDB
* @suppress PhanTypeMismatchProperty * @suppress PhanTypeMismatchProperty
*/ */
public static function db() public static function db()
@@ -61,11 +61,6 @@ class DB
if (self::$uDB === null) { if (self::$uDB === null) {
self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding); self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding);
self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true; self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
self::$uDB->error_handler = function () {
};
self::$uDB->throw_exception_on_error = true;
self::$uDB->throw_exception_on_nonsql_error = true;
} }
return self::$uDB; return self::$uDB;
} }
+53
View File
@@ -0,0 +1,53 @@
<?php
namespace sammo;
use sammo\DTO\MenuItem;
use sammo\DTO\MenuMulti;
use sammo\DTO\MenuSplit;
//변경을 원한다면 파일을 복제 후 수정
class GlobalMenu {
/** @var (MenuItem|MenuMulti|MenuSplit)[] */
const version = 3;
static ?array $menu = null;
public static function getMenu(): array{
if(static::$menu !== null){
return static::$menu;
}
static::$menu = [
new MenuItem('천통국 베팅', 'v_nationBetting.php', condHighlightVar: 'nationBetting'),
new MenuMulti('게임정보', [
new MenuItem('세력일람', 'a_kingdomList.php', newTab: true),
new MenuItem('장수일람', 'a_genList.php', newTab: true),
new MenuItem('명장일람', 'a_bestGeneral.php', newTab: true),
new MenuItem('명예의전당', 'a_hallOfFame.php', newTab: true),
new MenuItem('왕조일람', 'a_emperior.php', newTab: true),
]),
new MenuItem('연감', 'v_history.php', newTab: true),
new MenuSplit(
new MenuItem('게시판', '/board/community', newTab: true),
[
new MenuItem('건의/제안', '/board/request', newTab: true),
new MenuItem('팁/강좌', '/board/tip', newTab: true),
new MenuItem('패치 내역', '/board/patch', newTab: true),
]
),
new MenuSplit(
new MenuItem('공식 오픈 톡', 'https://open.kakao.com/o/', newTab: true),
[
new MenuItem('잡담 오픈 톡', 'https://open.kakao.com/o/', newTab: true)
],
),
new MenuItem('전투 시뮬레이터', 'battle_simulator.php', newTab: true),
new MenuMulti('기타 정보', [
new MenuItem('접속량정보', 'a_traffic.php', newTab: true),
new MenuItem('빙의일람', 'a_npcList', newTab: true, condShowVar: 'npcMode'),
]),
new MenuItem('설문조사', 'v_vote.php', newTab: true, condHighlightVar: 'vote'),
];
return static::$menu;
}
}
+6
View File
@@ -0,0 +1,6 @@
<?php
namespace sammo;
class ServerEnv extends ServerDefaultEnv {
//ServerEnv 기본값을 변경하고 싶다면 orig를 제거한 복사본을 만들고 수정
}
+1
View File
@@ -5,6 +5,7 @@ class UniqueConst{
public static $serverID = '_tK_serverID_'; public static $serverID = '_tK_serverID_';
public static $serverName = '_tK_serverName_'; public static $serverName = '_tK_serverName_';
public static $seasonIdx = '_tK_seasonIdx_'; public static $seasonIdx = '_tK_seasonIdx_';
public static $hiddenSeed = '_tK_hiddenSeed_';
private function __construct(){} private function __construct(){}
+16 -18
View File
@@ -1,18 +1,16 @@
<div class="buttonPlate"> <?=$btnBegin??''?><a href="v_nationBetting.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">천통국 베팅</a><?=$btnEnd??''?>
<a href="a_status.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력도</button></a> <?=$btnBegin??''?><a href="a_kingdomList.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">세력일람</a><?=$btnEnd??''?>
<a href="a_kingdomList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력일람</button></a> <?=$btnBegin??''?><a href="a_genList.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">장수일람</a><?=$btnEnd??''?>
<a href="a_genList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">장수일람</button></a> <?=$btnBegin??''?><a href="a_bestGeneral.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">명장일람</a><?=$btnEnd??''?>
<a href="a_bestGeneral.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명장일람</button></a> <?=$btnBegin??''?><a href="a_history.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">연감</a><?=$btnEnd??''?>
<a href="a_history.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">연감</button></a> <?=$btnBegin??''?><a href="a_hallOfFame.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">명예의전당</a><?=$btnEnd??''?>
<a href="a_hallOfFame.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명예의전당</button></a> <?=$btnBegin??''?><a href="a_emperior.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">왕조일람</a><?=$btnEnd??''?>
<a href="a_emperior.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">왕조일람</button></a> <?=$btnBegin??''?><a href="a_traffic.php" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>">접속량정보</a><?=$btnEnd??''?>
<a href="a_traffic.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">접속량정보</button></a> <?=$btnBegin??''?><a href="/bbs/board" target="_blank" class="toolbarButton2 <?=$btnClass??""?>">삼모게시판</a><?=$btnEnd??''?>
<a href="/bbs/board" target="_blank"><button type="button" class="toolbarButton2">삼모게시판</button></a> <?=$btnBegin??''?><a href="/bbs/tip" target="_blank" class="toolbarButton <?=$btnClass??""?>">팁/강좌</a><?=$btnEnd??''?>
<a href="/bbs/tip" target="_blank"><button type="button" class="toolbarButton">팁/강좌</button></a> <?=$btnBegin??''?><a href="/bbs/news" target="_blank" class="toolbarButton <?=$btnClass??""?>">삼국 일보</a><?=$btnEnd??''?>
<a href="/bbs/news" target="_blank"><button type="button" class="toolbarButton">삼국 일보</button></a> <?=$btnBegin??''?><a href="/bbs/history2" target="_blank" class="toolbarButton <?=$btnClass??""?>">개인 열전</a><?=$btnEnd??''?>
<a href="/bbs/history2" target="_blank"><button type="button" class="toolbarButton">개인 열전</button></a> <?=$btnBegin??''?><a href="/bbs/history3" target="_blank" class="toolbarButton <?=$btnClass??""?>">국가 열전</a><?=$btnEnd??''?>
<a href="/bbs/history3" target="_blank"><button type="button" class="toolbarButton">국가 열전</button></a> <?=$btnBegin??''?><a href="/bbs/patch" target="_blank" class="toolbarButton <?=$btnClass??""?>">패치 내역</a><?=$btnEnd??''?>
<a href="/bbs/patch" target="_blank"><button type="button" class="toolbarButton">패치 내역</button></a> <?=$btnBegin??''?><a href="battle_simulator.php" target="_blank" class="toolbarButton <?=$btnClass??""?>">전투 시뮬레이터</a><?=$btnEnd??''?>
<a href="battle_simulator.php" target="_blank"><button type="button" class="toolbarButton">전투 시뮬레이터</button></a> <?=$btnBegin??''?><a href="<?= $site ?>" target="_blank" class="open-window toolbarButton <?=$btnClass??""?>"><?= $call ?></a><?=$btnEnd??''?>
<a href="<?=$site?>" target="_blank" class="open-window"><button type="button" class="toolbarButton"><?=$call?></button></a>
</div>
+233 -472
View File
@@ -3,7 +3,13 @@
namespace sammo; namespace sammo;
use DateTime; use DateTime;
use sammo\Event\Action; use Ds\Set;
use sammo\Enums\AuctionType;
use sammo\Enums\GeneralAccessLogColumn;
use sammo\Enums\GeneralColumn;
use sammo\Enums\GeneralQueryMode;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
require_once 'process_war.php'; require_once 'process_war.php';
require_once 'func_gamerule.php'; require_once 'func_gamerule.php';
@@ -100,10 +106,9 @@ function GetImageURL($imgsvr, $filepath = '')
} }
/** /**
* @param null|int $con 장수의 벌점 * @param null|int $refreshScore 장수의 벌점
* @param null|int $conlimit 최대 벌점
*/ */
function checkLimit($con = null) function checkLimit($refreshScore = null)
{ {
$session = Session::getInstance(); $session = Session::getInstance();
if ($session->userGrade >= 4) { if ($session->userGrade >= 4) {
@@ -113,15 +118,15 @@ function checkLimit($con = null)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
if ($con === null) { if ($refreshScore === null) {
$con = $db->queryFirstField('SELECT con FROM general WHERE `owner`=%i', Session::getUserID()); $refreshScore = $db->queryFirstField('SELECT refresh_score FROM general_access_log WHERE `general_id`=%i', Session::getGeneralID());
} }
$conlimit = $gameStor->conlimit; $refreshLimit = $gameStor->refreshLimit;
if ($con > $conlimit) { if ($refreshScore > $refreshLimit) {
return 2; return 2;
//접속제한 90%이면 경고문구 //접속제한 90%이면 경고문구
} elseif ($con > $conlimit * 0.9) { } elseif ($refreshScore > $refreshLimit * 0.9) {
return 1; return 1;
} else { } else {
return 0; return 0;
@@ -133,18 +138,18 @@ function getBlockLevel()
return DB::db()->queryFirstField('select block from general where no = %i', Session::getInstance()->generalID); return DB::db()->queryFirstField('select block from general where no = %i', Session::getInstance()->generalID);
} }
function getRandGenName() function getRandGenName(RandUtil $rng)
{ {
$firstname = Util::choiceRandom(GameConst::$randGenFirstName); $firstname = $rng->choice(GameConst::$randGenFirstName);
$middlename = Util::choiceRandom(GameConst::$randGenMiddleName); $middlename = $rng->choice(GameConst::$randGenMiddleName);
$lastname = Util::choiceRandom(GameConst::$randGenLastName); $lastname = $rng->choice(GameConst::$randGenLastName);
return "{$firstname}{$middlename}{$lastname}"; return "{$firstname}{$middlename}{$lastname}";
} }
function cityInfo(General $generalObj) function cityInfo(GeneralLite $generalObj)
{ {
$db = DB::db(); $db = DB::db();
@@ -171,7 +176,7 @@ function cityInfo(General $generalObj)
]; ];
foreach ($db->query('SELECT `officer_level`, `name`, npc, no FROM general WHERE officer_city = %i', $cityID) as $officer) { foreach ($db->query('SELECT `officer_level`, `name`, npc, no FROM general WHERE officer_city = %i', $cityID) as $officer) {
$officerName[$officer['officer_level']] = getColoredName($officer['name'], $officer['npc']); $officerName[$officer['officer_level']] = formatName($officer['name'], $officer['npc']);
} }
$city['officerName'] = $officerName; $city['officerName'] = $officerName;
@@ -199,8 +204,8 @@ function myNationInfo(General $generalObj)
$topChiefs = Util::convertArrayToDict($db->query('SELECT officer_level, no, name, npc FROM general WHERE nation = %i AND officer_level >= 11', $nationID), 'officer_level'); $topChiefs = Util::convertArrayToDict($db->query('SELECT officer_level, no, name, npc FROM general WHERE nation = %i AND officer_level >= 11', $nationID), 'officer_level');
$level12Name = key_exists(12, $topChiefs) ? getColoredName($topChiefs[12]['name'], $topChiefs[12]['npc']) : '-'; $level12Name = key_exists(12, $topChiefs) ? formatName($topChiefs[12]['name'], $topChiefs[12]['npc']) : '-';
$level11Name = key_exists(11, $topChiefs) ? getColoredName($topChiefs[11]['name'], $topChiefs[11]['npc']) : '-'; $level11Name = key_exists(11, $topChiefs) ? formatName($topChiefs[11]['name'], $topChiefs[11]['npc']) : '-';
$impossibleStrategicCommandLists = []; $impossibleStrategicCommandLists = [];
$strategicCommandLists = GameConst::$availableChiefCommand['전략']; $strategicCommandLists = GameConst::$availableChiefCommand['전략'];
@@ -403,14 +408,14 @@ function checkSecretPermission(array $me, $checkSecretLimit = true)
} }
$secretMin = 0; $secretMin = 0;
$secretMax = checkSecretMaxPermission($me, $penalty); $secretMax = checkSecretMaxPermission($penalty);
if ($me['officer_level'] == 12) { if ($me['officer_level'] == 12) {
$secretMin = 4; $secretMin = 4;
} else if ($me['permission'] == 'ambassador') { } else if ($permission == 'ambassador') {
$secretMin = 4; $secretMin = 4;
} else if ($me['permission'] == 'auditor') { } else if ($permission == 'auditor') {
$secretMin = 3; $secretMin = 3;
} else if ($me['officer_level'] >= 5) { } else if ($me['officer_level'] >= 5) {
$secretMin = 2; $secretMin = 2;
@@ -472,7 +477,8 @@ function getCommandTable(General $general)
return $result; return $result;
} }
function getChiefCommandTable(General $general){ function getChiefCommandTable(General $general)
{
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->turnOnCache(); $gameStor->turnOnCache();
@@ -638,7 +644,7 @@ function generalInfo(General $generalObj)
$age = "<font color=red>{$age} 세</font>"; $age = "<font color=red>{$age} 세</font>";
} }
$connectCnt = round($generalObj->getVar('connect'), -1); $refreshScoreTotal = round($generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScoreTotal) ?? 0, -1);
$specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic $specialDomestic = $generalObj->getVar('special') === GameConst::$defaultSpecialDomestic
? "{$generalObj->getVar('specage')}세" ? "{$generalObj->getVar('specage')}세"
: "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>"; : "<font color=limegreen>" . displayiActionObjInfo($generalObj->getSpecialDomestic()) . "</font>";
@@ -747,7 +753,7 @@ function generalInfo(General $generalObj)
<td style='text-align:center;' class='bg1'><b>부대</b></td> <td style='text-align:center;' class='bg1'><b>부대</b></td>
<td style='text-align:center;' colspan=3>{$troopInfo}</td> <td style='text-align:center;' colspan=3>{$troopInfo}</td>
<td style='text-align:center;' class='bg1'><b>벌점</b></td> <td style='text-align:center;' class='bg1'><b>벌점</b></td>
<td style='text-align:center;' colspan=5>" . getConnect($connectCnt) . " {$connectCnt}({$generalObj->getVar('con')})</td> <td style='text-align:center;' colspan=5>" . getRefreshScoreText($refreshScoreTotal) . " {$refreshScoreTotal}({$generalObj->getAccessLogVar(GeneralAccessLogColumn::refreshScore)})</td>
</tr> </tr>
</table>"; </table>";
} }
@@ -756,8 +762,8 @@ function generalInfo2(General $generalObj)
{ {
$general = $generalObj->getRaw(); $general = $generalObj->getRaw();
$winRate = round($generalObj->getRankVar('killnum') / max($generalObj->getRankVar('warnum'), 1) * 100, 2); $winRate = round($generalObj->getRankVar(RankColumn::killnum) / max($generalObj->getRankVar(RankColumn::warnum), 1) * 100, 2);
$killRate = round($generalObj->getRankVar('killcrew') / max($generalObj->getRankVar('deathcrew'), 1) * 100, 2); $killRate = round($generalObj->getRankVar(RankColumn::killcrew) / max($generalObj->getRankVar(RankColumn::deathcrew), 1) * 100, 2);
$experienceBonus = $generalObj->onCalcStat($generalObj, 'experience', 10000) - 10000; $experienceBonus = $generalObj->onCalcStat($generalObj, 'experience', 10000) - 10000;
if ($experienceBonus > 0) { if ($experienceBonus > 0) {
@@ -821,9 +827,9 @@ function generalInfo2(General $generalObj)
</tr> </tr>
<tr> <tr>
<td width=64 style='text-align:center;' class='bg1'><b>전투</b></td> <td width=64 style='text-align:center;' class='bg1'><b>전투</b></td>
<td width=132 style='text-align:center;'>{$generalObj->getRankVar('warnum')}</td> <td width=132 style='text-align:center;'>{$generalObj->getRankVar(RankColumn::warnum)}</td>
<td width=48 style='text-align:center;' class='bg1'><b>계략</b></td> <td width=48 style='text-align:center;' class='bg1'><b>계략</b></td>
<td width=98 style='text-align:center;'>{$generalObj->getRankVar('firenum')}</td> <td width=98 style='text-align:center;'>{$generalObj->getRankVar(RankColumn::firenum)}</td>
<td width=48 style='text-align:center;' class='bg1'><b>사관</b></td> <td width=48 style='text-align:center;' class='bg1'><b>사관</b></td>
<td width=98 style='text-align:center;'>{$general['belong']}년</td> <td width=98 style='text-align:center;'>{$general['belong']}년</td>
</tr> </tr>
@@ -831,17 +837,17 @@ function generalInfo2(General $generalObj)
<td style='text-align:center;' class='bg1'><b>승률</b></td> <td style='text-align:center;' class='bg1'><b>승률</b></td>
<td style='text-align:center;'>{$winRate} %</td> <td style='text-align:center;'>{$winRate} %</td>
<td style='text-align:center;' class='bg1'><b>승리</b></td> <td style='text-align:center;' class='bg1'><b>승리</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('killnum')}</td> <td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::killnum)}</td>
<td style='text-align:center;' class='bg1'><b>패배</b></td> <td style='text-align:center;' class='bg1'><b>패배</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('deathnum')}</td> <td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::deathnum)}</td>
</tr> </tr>
<tr> <tr>
<td style='text-align:center;' class='bg1'><b>살상률</b></td> <td style='text-align:center;' class='bg1'><b>살상률</b></td>
<td style='text-align:center;'>{$killRate} %</td> <td style='text-align:center;'>{$killRate} %</td>
<td style='text-align:center;' class='bg1'><b>사살</b></td> <td style='text-align:center;' class='bg1'><b>사살</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('killcrew')}</td> <td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::killcrew)}</td>
<td style='text-align:center;' class='bg1'><b>피살</b></td> <td style='text-align:center;' class='bg1'><b>피살</b></td>
<td style='text-align:center;'>{$generalObj->getRankVar('deathcrew')}</td> <td style='text-align:center;'>{$generalObj->getRankVar(RankColumn::deathcrew)}</td>
</tr> </tr>
</table> </table>
<table width=498 class='tb_layout bg2 f_tnum'> <table width=498 class='tb_layout bg2 f_tnum'>
@@ -879,9 +885,9 @@ function generalInfo2(General $generalObj)
</table>"; </table>";
} }
function getOnlineNum() function getOnlineNum(): int
{ {
return KVStorage::getStorage(DB::db(), 'game_env')->online; return KVStorage::getStorage(DB::db(), 'game_env')->getValue('online_user_cnt') ?? 0;
} }
function onlinegen(General $general) function onlinegen(General $general)
@@ -901,7 +907,7 @@ function nationMsg(General $general)
$nationID = $general->getNationID(); $nationID = $general->getNationID();
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env'); $nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
return $nationStor->notice ?? ''; return $nationStor->nationNotice['msg'] ?? '';
} }
function banner() function banner()
@@ -994,76 +1000,69 @@ function increaseRefresh($type = "", $cnt = 1)
$generalID = $session->generalID; $generalID = $session->generalID;
$userGrade = $session->userGrade; $userGrade = $session->userGrade;
$date = TimeUtil::now(); $dateObj = new \DateTimeImmutable();
$date = TimeUtil::format($dateObj, false);
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
$isunited = $gameStor->isunited; $isunited = $gameStor->isunited;
$opentime = $gameStor->opentime; $opentime = $gameStor->opentime;
if ($isunited != 2 && $generalID && $userGrade < 6 && $opentime <= TimeUtil::now()) { if ($userGrade == 6) {
$db->update('general', [ return;
'lastrefresh' => $date, }
'con' => $db->sqleval('con + %i', $cnt), if ($isunited == 2) {
'connect' => $db->sqleval('connect + %i', $cnt), return;
'refcnt' => $db->sqleval('refcnt + %i', $cnt), }
'refresh' => $db->sqleval('refresh + %i', $cnt) if (!$generalID) {
], 'owner=%i', $userID); return;
}
if ($opentime > $date) {
return;
} }
$date = date('Y_m_d H:i:s'); $gameStor->refresh = $gameStor->refresh + $cnt; //TODO: +로 증가하는 값은 별도로 분리
$date2 = substr($date, 0, 10);
$online = getOnlineNum();
file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_refresh.txt",
sprintf(
"%s, %s, %s, %s, %s, %d\n",
$date,
$session->userName,
$session->generalName,
$session->ip,
$type,
$online
),
FILE_APPEND
);
$proxy_headers = array( $db->insertUpdate('general_access_log', [
'HTTP_VIA', GeneralAccessLogColumn::generalID->value => $generalID,
'HTTP_X_FORWARDED_FOR', GeneralAccessLogColumn::userID->value => $userID,
'HTTP_FORWARDED_FOR', GeneralAccessLogColumn::lastRefresh->value => $date,
'HTTP_X_FORWARDED', GeneralAccessLogColumn::refreshTotal->value => $cnt,
'HTTP_FORWARDED', GeneralAccessLogColumn::refresh->value => $cnt,
'HTTP_CLIENT_IP', GeneralAccessLogColumn::refreshScore->value => $cnt,
'HTTP_FORWARDED_FOR_IP', GeneralAccessLogColumn::refreshScoreTotal->value => $cnt,
'VIA', ], [
'X_FORWARDED_FOR', GeneralAccessLogColumn::lastRefresh->value => $date,
'FORWARDED_FOR', GeneralAccessLogColumn::refreshTotal->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshTotal->value, $cnt),
'X_FORWARDED', GeneralAccessLogColumn::refresh->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refresh->value, $cnt),
'FORWARDED', GeneralAccessLogColumn::refreshScore->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshScore->value, $cnt),
'CLIENT_IP', GeneralAccessLogColumn::refreshScoreTotal->value => $db->sqleval('%b + %i', GeneralAccessLogColumn::refreshScoreTotal->value, $cnt),
'FORWARDED_FOR_IP', ]);
'HTTP_PROXY_CONNECTION'
);
$str = ""; $serverPath = __DIR__;
foreach ($proxy_headers as $x) {
if (isset($_SERVER[$x])) $str .= "//{$x}:{$_SERVER[$x]}"; $serverID = UniqueConst::$serverID;
} $logPath = "{$serverPath}/logs/{$serverID}/api_log.db";
if ($str != "") {
file_put_contents( $logDB = FileDB::db($logPath, $serverPath . '/../f_install/sql/api_log.sql');
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_{$date2}_ipcheck.txt",
sprintf( $ip = $_SERVER['REMOTE_ADDR'] ?? 'local';
"%s, %s, %s%s\n", $date = date('Y-m-d H:i:s');
$session->userName,
$session->generalName, $logDB->insert('api_log', [
$_SERVER['REMOTE_ADDR'], 'user_id' => $session->userID,
$str 'ip' => $ip,
), 'date' => $date,
FILE_APPEND 'path' => "refresh",
); 'arg' => Json::encode([
} 'type' => $type,
]),
'aux' => Json::encode([
'generalID' => $generalID,
'generalName' => $session->generalName,
'userName' => $session->userName,
]),
]);
} }
function updateTraffic() function updateTraffic()
@@ -1071,10 +1070,8 @@ function updateTraffic()
$online = getOnlineNum(); $online = getOnlineNum();
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh']); $admin = $gameStor->getValues(['year', 'month', 'refresh', 'maxonline', 'maxrefresh', 'recentTraffic']);
/** @var array{year:int,month:int,refresh:int,maxonline:int,maxrefresh:int} $admin */
//최다갱신자
$user = $db->queryFirstRow('select name,refresh from general order by refresh desc limit 1');
if ($admin['maxrefresh'] < $admin['refresh']) { if ($admin['maxrefresh'] < $admin['refresh']) {
$admin['maxrefresh'] = $admin['refresh']; $admin['maxrefresh'] = $admin['refresh'];
@@ -1086,22 +1083,20 @@ function updateTraffic()
$gameStor->maxrefresh = $admin['maxrefresh']; $gameStor->maxrefresh = $admin['maxrefresh'];
$gameStor->maxonline = $admin['maxonline']; $gameStor->maxonline = $admin['maxonline'];
$db->update('general', ['refresh' => 0], true); $recentTraffic = $admin['recentTraffic'] ?? [];
if(count($recentTraffic) >= 5){
array_shift($recentTraffic);
}
$recentTraffic[] = [
'year'=>$admin['year'],
'month' => $admin['month'],
'refresh' => $admin['refresh'],
'online' => $online,
'date' => TimeUtil::now(),
];
$gameStor->recentTraffic = $recentTraffic;
$date = TimeUtil::now(); $db->update('general_access_log', ['refresh' => 0], true);
//일시|년|월|총갱신|접속자|최다갱신자
file_put_contents(
__DIR__ . "/logs/" . UniqueConst::$serverID . "/_traffic.txt",
Json::encode([
$date,
$admin['year'],
$admin['month'],
$admin['refresh'],
$online,
$user['name'] . "(" . $user['refresh'] . ")"
]) . "\n",
FILE_APPEND
);
} }
function CheckOverhead() function CheckOverhead()
@@ -1109,19 +1104,19 @@ function CheckOverhead()
//서버정보 //서버정보
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
list($turnterm, $conlimit) = $gameStor->getValuesAsArray(['turnterm', 'conlimit']); [$turnterm, $refreshLimit] = $gameStor->getValuesAsArray(['turnterm', 'refreshLimit']);
$con = Util::round(pow($turnterm, 0.6) * 3) * 10; $nextRefreshLimit = Util::round(pow($turnterm, 0.6) * 3) * 10;
if ($con != $conlimit) { if ($nextRefreshLimit != $refreshLimit) {
$gameStor->conlimit = $con; $gameStor->refreshLimit = $nextRefreshLimit;
} }
} }
function isLock() function isLock()
{ {
return DB::db()->queryFirstField("SELECT plock from plock limit 1") != 0; return DB::db()->queryFirstField("SELECT plock from plock WHERE `type`='GAME'") != 0;
} }
function tryLock(): bool function tryLock(): bool
@@ -1133,7 +1128,7 @@ function tryLock(): bool
$db->update('plock', [ $db->update('plock', [
'plock' => 1, 'plock' => 1,
'locktime' => TimeUtil::now(true) 'locktime' => TimeUtil::now(true)
], 'plock=0'); ], 'plock=0 AND type="GAME"');
return $db->affectedRows() > 0; return $db->affectedRows() > 0;
} }
@@ -1144,7 +1139,7 @@ function unlock(): bool
$db = DB::db(); $db = DB::db();
$db->update('plock', [ $db->update('plock', [
'plock' => 0 'plock' => 0
], true); ], 'type="GAME"');
return $db->affectedRows() > 0; return $db->affectedRows() > 0;
} }
@@ -1200,9 +1195,9 @@ function checkDelay()
$db->update('general', [ $db->update('general', [
'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute) 'turntime' => $db->sqleval('DATE_ADD(turntime, INTERVAL %i MINUTE)', $minute)
], 'turntime<=DATE_ADD(turntime, INTERVAL %i MINUTE)', $term); ], 'turntime<=DATE_ADD(turntime, INTERVAL %i MINUTE)', $term);
$db->update('auction', [ $db->update('ng_auction', [
'expire' => $db->sqleval('DATE_ADD(expire, INTERVAL %i MINUTE)', $minute) 'close_date' => $db->sqleval('DATE_ADD(close_date, INTERVAL %i MINUTE)', $minute)
], true); ], 'finished = 0');
} }
} }
@@ -1217,10 +1212,18 @@ function updateOnline()
$nationname[$nation['nation']] = $nation['name']; $nationname[$nation['nation']] = $nation['name'];
} }
//동접수 //동접수
$before5Min = TimeUtil::nowAddMinutes(-5); $startTurn = cutTurn($gameStor->turntime, $gameStor->turnterm, false);
$onlineUser = $db->query('SELECT no,name,nation FROM general WHERE lastrefresh > %s AND npc < 2', $before5Min); $onlineUser = $db->query(
'SELECT %b, %b, %b FROM `general_access_log` as `log` INNER JOIN `general` ON `log`.%b = `general`.%b WHERE %b >= %s',
GeneralColumn::no->value,
GeneralColumn::name->value,
GeneralColumn::nation->value,
GeneralAccessLogColumn::generalID->value,
GeneralColumn::no->value,
GeneralAccessLogColumn::lastRefresh->value,
$startTurn
);
$onlineNum = count($onlineUser); $onlineNum = count($onlineUser);
$onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation'); $onlineNationUsers = Util::arrayGroupBy($onlineUser, 'nation');
@@ -1243,74 +1246,6 @@ function updateOnline()
$gameStor->online_nation = join(', ', $onlineNation); $gameStor->online_nation = join(', ', $onlineNation);
} }
function addAge()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
//나이와 호봉 증가
$db->update('general', [
'age' => $db->sqleval('age+1'),
], true);
$db->update('general', [
'belong' => $db->sqleval('belong+1')
], 'nation != 0');
[$startYear, $year, $month] = $gameStor->getValuesAsArray(['startyear', 'year', 'month']);
if ($year >= $startYear + 3) {
foreach ($db->query('SELECT no,name,nation,leadership,strength,intel,aux from general where specage<=age and special=%s', GameConst::$defaultSpecialDomestic) as $general) {
$generalID = $general['no'];
$special = SpecialityHelper::pickSpecialDomestic(
$general,
(Json::decode($general['aux'])['prev_types_special']) ?? []
);
$specialClass = buildGeneralSpecialDomesticClass($special);
$specialText = $specialClass->getName();
$db->update('general', [
'special' => $special
], 'no=%i', $generalID);
$logger = new ActionLogger($generalID, $general['nation'], $year, $month);
$josaUl = JosaUtil::pick($specialText, '을');
$logger->pushGeneralActionLog("특기 【<b><L>{$specialText}</></b>】{$josaUl} 익혔습니다!", ActionLogger::PLAIN);
$logger->pushGeneralHistoryLog("특기 【<b><C>{$specialText}</></b>】{$josaUl} 습득");
}
foreach ($db->query('SELECT no,name,nation,leadership,strength,intel,npc,dex1,dex2,dex3,dex4,dex5,aux from general where specage2<=age and special2=%s', GameConst::$defaultSpecialWar) as $general) {
$generalID = $general['no'];
$generalAux = Json::decode($general['aux']);
$updateVars = [];
if (key_exists('inheritSpecificSpecialWar', $generalAux)) {
$special2 = $generalAux['inheritSpecificSpecialWar'];
unset($generalAux['inheritSpecificSpecialWar']);
$updateVars['aux'] = Json::encode($generalAux);
} else {
$special2 = SpecialityHelper::pickSpecialWar(
$general,
($generalAux['prev_types_special2']) ?? []
);
}
$specialClass = buildGeneralSpecialWarClass($special2);
$specialText = $specialClass->getName();
$updateVars['special2'] = $special2;
$db->update('general', $updateVars, 'no=%i', $general['no']);
$logger = new ActionLogger($generalID, $general['nation'], $year, $month);
$josaUl = JosaUtil::pick($specialText, '을');
$logger->pushGeneralActionLog("특기 【<b><L>{$specialText}</></b>】{$josaUl} 익혔습니다!", ActionLogger::PLAIN);
$logger->pushGeneralHistoryLog("특기 【<b><C>{$specialText}</></b>】{$josaUl} 습득");
}
}
}
function turnDate($curtime) function turnDate($curtime)
{ {
$db = DB::db(); $db = DB::db();
@@ -1339,7 +1274,7 @@ function turnDate($curtime)
} }
function triggerTournament() function triggerTournament(RandUtil $rng)
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1350,10 +1285,10 @@ function triggerTournament()
if ($tournament != 0) { if ($tournament != 0) {
return; return;
} }
if ($tnmt_trig == 0) { if (!$tnmt_trig) {
return; return;
} }
if (!Util::randBool(0.4)) { if (!$rng->nextBool(0.4)) {
return; return;
} }
@@ -1366,7 +1301,7 @@ function triggerTournament()
$tnmt_type = array_pop($tnmt_pattern); $tnmt_type = array_pop($tnmt_pattern);
$gameStor->setValue('tnmt_pattern', $tnmt_pattern); $gameStor->setValue('tnmt_pattern', $tnmt_pattern);
startTournament($tnmt_trig, $tnmt_type); startTournament($tnmt_type);
} }
function CheckHall($no) function CheckHall($no)
@@ -1374,6 +1309,7 @@ function CheckHall($no)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
//TODO: Enum타입을 두종류로 넣고, raw string이면 calcVar에서 받아오면?
$types = [ $types = [
["experience", 'natural'], ["experience", 'natural'],
["dedication", 'natural'], ["dedication", 'natural'],
@@ -1401,35 +1337,35 @@ function CheckHall($no)
["betrate", 'calc'], ["betrate", 'calc'],
]; ];
$generalObj = General::createGeneralObjFromDB($no, null, 2); $generalObj = General::createObjFromDB($no);
$ttw = $generalObj->getRankVar('ttw'); $ttw = $generalObj->getRankVar(RankColumn::ttw);
$ttd = $generalObj->getRankVar('ttd'); $ttd = $generalObj->getRankVar(RankColumn::ttd);
$ttl = $generalObj->getRankVar('ttl'); $ttl = $generalObj->getRankVar(RankColumn::ttl);
$tlw = $generalObj->getRankVar('tlw'); $tlw = $generalObj->getRankVar(RankColumn::tlw);
$tld = $generalObj->getRankVar('tld'); $tld = $generalObj->getRankVar(RankColumn::tld);
$tll = $generalObj->getRankVar('tll'); $tll = $generalObj->getRankVar(RankColumn::tll);
$tsw = $generalObj->getRankVar('tsw'); $tsw = $generalObj->getRankVar(RankColumn::tsw);
$tsd = $generalObj->getRankVar('tsd'); $tsd = $generalObj->getRankVar(RankColumn::tsd);
$tsl = $generalObj->getRankVar('tsl'); $tsl = $generalObj->getRankVar(RankColumn::tsl);
$tiw = $generalObj->getRankVar('tiw'); $tiw = $generalObj->getRankVar(RankColumn::tiw);
$tid = $generalObj->getRankVar('tid'); $tid = $generalObj->getRankVar(RankColumn::tid);
$til = $generalObj->getRankVar('til'); $til = $generalObj->getRankVar(RankColumn::til);
$betWinGold = $generalObj->getRankVar('betwingold'); $betWinGold = $generalObj->getRankVar(RankColumn::betwingold);
$betGold = Util::valueFit($generalObj->getRankVar('betgold'), 1); $betGold = Util::valueFit($generalObj->getRankVar(RankColumn::betgold), 1);
$win = $generalObj->getRankVar('killnum'); $win = $generalObj->getRankVar(RankColumn::killnum);
$war = Util::valueFit($generalObj->getRankVar('warnum'), 1); $war = Util::valueFit($generalObj->getRankVar(RankColumn::warnum), 1);
$kill = $generalObj->getRankVar('killcrew'); $kill = $generalObj->getRankVar(RankColumn::killcrew);
$death = Util::valueFit($generalObj->getRankVar('deathcrew'), 1); $death = Util::valueFit($generalObj->getRankVar(RankColumn::deathcrew), 1);
$killPerson = $generalObj->getRankVar('killcrew_person'); $killPerson = $generalObj->getRankVar(RankColumn::killcrew_person);
$deathPerson = Util::valueFit($generalObj->getRankVar('deathcrew_person'), 1); $deathPerson = Util::valueFit($generalObj->getRankVar(RankColumn::deathcrew_person), 1);
$tt = Util::valueFit($ttw + $ttd + $ttl, 1); $tt = Util::valueFit($ttw + $ttd + $ttl, 1);
$tl = Util::valueFit($tlw + $tld + $tll, 1); $tl = Util::valueFit($tlw + $tld + $tll, 1);
@@ -1467,13 +1403,13 @@ function CheckHall($no)
if ($valueType === 'natural') { if ($valueType === 'natural') {
$value = $generalObj->getVar($typeName); $value = $generalObj->getVar($typeName);
} else if ($valueType === 'rank') { } else if ($valueType === 'rank') {
$value = $generalObj->getRankVar($typeName); $value = $generalObj->getRankVar(RankColumn::from($typeName));
} else if ($valueType === 'calc') { } else if ($valueType === 'calc') {
$value = $calcVar[$typeName]; $value = $calcVar[$typeName];
} }
//승률,살상률인데 10회 미만 전투시 스킵 //승률,살상률인데 10회 미만 전투시 스킵
if (($typeName === 'winrate' || $typeName === 'killrate') && $generalObj->getRankVar('warnum') < 10) { if (($typeName === 'winrate' || $typeName === 'killrate') && $generalObj->getRankVar(RankColumn::warnum) < 10) {
continue; continue;
} }
//토너승률인데 50회 미만시 스킵 //토너승률인데 50회 미만시 스킵
@@ -1493,7 +1429,7 @@ function CheckHall($no)
continue; continue;
} }
//수익률인데 1000미만시 스킵 //수익률인데 1000미만시 스킵
if ($typeName === 'betrate' && $generalObj->getRankVar('betgold') < 1000) { if ($typeName === 'betrate' && $generalObj->getRankVar(RankColumn::betgold) < 1000) {
continue; continue;
} }
@@ -1547,9 +1483,10 @@ function CheckHall($no)
} }
} }
function giveRandomUniqueItem(General $general, string $acquireType): bool function giveRandomUniqueItem(RandUtil $rng, General $general, string $acquireType): bool
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
//아이템 습득 상황 //아이템 습득 상황
$availableUnique = []; $availableUnique = [];
@@ -1581,7 +1518,19 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
} }
} }
foreach($db->queryAllLists('SELECT namespace, count(*) as cnt FROM `storage` WHERE namespace LIKE "ut_%" GROUP BY namespace') as [$uniqueNS, $cnt]){ $auctionItems = $db->queryFirstColumn(
'SELECT `target` FROM `ng_auction` WHERE `type` = %s AND `finished` = 0',
AuctionType::UniqueItem->value
);
foreach ($auctionItems as $itemCode) {
if (key_exists($itemCode, $occupiedUnique)) {
$occupiedUnique[$itemCode]++;
} else {
$occupiedUnique[$itemCode] = 1;
}
}
foreach ($db->queryAllLists('SELECT namespace, count(*) as cnt FROM `storage` WHERE namespace LIKE "ut_%" GROUP BY namespace') as [$uniqueNS, $cnt]) {
$itemCode = substr($uniqueNS, 3); $itemCode = substr($uniqueNS, 3);
$itemClass = buildItemClass($itemCode); $itemClass = buildItemClass($itemCode);
if (!$itemClass) { if (!$itemClass) {
@@ -1590,7 +1539,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
if ($itemClass->isBuyable()) { if ($itemClass->isBuyable()) {
continue; continue;
} }
$occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode]??0) + $cnt; $occupiedUnique[$itemCode] = ($occupiedUnique[$itemCode] ?? 0) + $cnt;
} }
foreach (GameConst::$allItems as $itemType => $itemCategories) { foreach (GameConst::$allItems as $itemType => $itemCategories) {
@@ -1616,28 +1565,26 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
if (!$availableUnique) { if (!$availableUnique) {
if ($general->getAuxVar('inheritRandomUnique')) { if ($general->getAuxVar('inheritRandomUnique')) {
$general->setAuxVar('inheritRandomUnique', null); $general->setAuxVar('inheritRandomUnique', null);
$general->increaseInheritancePoint('previous', GameConst::$inheritItemRandomPoint); $general->increaseInheritancePoint(InheritanceKey::previous, GameConst::$inheritItemRandomPoint);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, -GameConst::$inheritItemRandomPoint);
$userLogger = new UserLogger($general->getVar('owner')); $userLogger = new UserLogger($general->getVar('owner'));
$userLogger->push(sprintf("얻을 유니크가 없어 %d 포인트 반환", GameConst::$inheritItemRandomPoint), "inheritPoint"); $userLogger->push(sprintf("얻을 유니크가 없어 %d 포인트 반환", GameConst::$inheritItemRandomPoint), "inheritPoint");
} }
return false; return false;
} }
if ($general->getAuxVar('inheritRandomUnique')) { if ($general->getAuxVar('inheritRandomUnique')) {
$gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month, $initYear, $initMonth] = $gameStor->getValuesAsArray(['year', 'month', 'init_year', 'init_month']); [$year, $month, $initYear, $initMonth] = $gameStor->getValuesAsArray(['year', 'month', 'init_year', 'init_month']);
$relMonthByInit = Util::joinYearMonth($year, $month) - Util::joinYearMonth($initYear, $initMonth); $relMonthByInit = Util::joinYearMonth($year, $month) - Util::joinYearMonth($initYear, $initMonth);
$availableBuyUnique = $relMonthByInit >= GameConst::$minMonthToAllowInheritItem; $availableBuyUnique = $relMonthByInit >= GameConst::$minMonthToAllowInheritItem;
if($availableBuyUnique){ if ($availableBuyUnique) {
$general->setAuxVar('inheritRandomUnique', null); $general->setAuxVar('inheritRandomUnique', null);
} }
} }
[$itemType, $itemCode] = Util::choiceRandomUsingWeightPair($availableUnique); [$itemType, $itemCode] = $rng->choiceUsingWeightPair($availableUnique);
$nationName = $general->getStaticNation()['name']; $nationName = $general->getStaticNation()['name'];
$generalName = $general->getName(); $generalName = $general->getName();
@@ -1660,208 +1607,7 @@ function giveRandomUniqueItem(General $general, string $acquireType): bool
return true; return true;
} }
function rollbackInheritUniqueTrial(General $general, string $itemKey, string $reason) function tryUniqueItemLottery(RandUtil $rng, General $general, string $acquireType = '아이템'): bool
{
$ownerID = $general->getVar('owner');
$db = DB::db();
$itemTrials = $general->getAuxVar('inheritUniqueTrial');
LogText("선택유니크 롤백:{$ownerID}", [$itemKey, $itemTrials]);
unset($itemTrials[$itemKey]);
if (count($itemTrials) == 0) {
$itemTrials = null;
}
$general->setAuxVar('inheritUniqueTrial', $itemTrials);
$trialStor = KVStorage::getStorage($db, "ut_{$itemKey}");
$ownTrial = $trialStor->getValue("u{$ownerID}");
$itemObj = buildItemClass($itemKey);
$itemName = $itemObj->getName();
if ($ownTrial) {
//두 값이 general, KVStorage 둘다 있고, 이중에선 KVStorage 값을 기준으로 하자 따르자
[,, $amount] = $ownTrial;
$trialStor->deleteValue("u{$ownerID}");
$general->increaseInheritancePoint('previous', $amount);
LogText("선택유니크 롤백포인트:{$ownerID}", $amount);
$userLogger = new UserLogger($ownerID);
$userLogger->push("{$itemName} 입찰에 사용한 {$amount} 포인트 반환", "inheritPoint");
}
//메시지
$staticNation = $general->getStaticNation();
$unlimited = new \DateTime('9999-12-31');
$src = new MessageTarget(0, '', 0, 'System', '#000000');
$dest = new MessageTarget($general->getID(), $general->getName(), $general->getNationID(), $staticNation['name'], $staticNation['color'], GetImageURL($general->getVar('imgsvr'), $general->getVar('picture')));
$josaUl = JosaUtil::pick($itemName, '을');
$msg = new Message(
Message::MSGTYPE_PRIVATE,
$src,
$dest,
"{$itemName}{$josaUl} 얻지 못했습니다. {$reason}",
new DateTime(),
$unlimited,
[]
);
$general->applyDB($db);
$msg->send(true);
}
function tryRollbackInheritUniqueItem(General $general): void
{
tryInheritUniqueItem($general, 'Rollback', true);
}
function tryInheritUniqueItem(General $general, string $acquireType = '아이템', bool $justRollback = false): bool
{
$ownerID = $general->getVar('owner');
if (!$ownerID) {
LogText("선택유니크 실패???: {$ownerID}", $general->getName());
return false;
}
$itemTrials = $general->getAuxVar('inheritUniqueTrial') ?? [];
arsort($itemTrials);
LogText("선택유니크항목: {$ownerID}", $itemTrials);
$db = DB::db();
$ownTarget = null;
$ownType = null;
foreach ($itemTrials as $itemKey => $amount) {
$availableItemTypes = [];
$reasons = [];
foreach (GameConst::$allItems as $itemType => $itemList) {
//아직은 그런 경우는 없지만 동일 유니크를 여러 부위에 장착할 수 있을지도 모름
if (!key_exists($itemKey, $itemList)) {
continue;
}
$ownItem = $general->getItem($itemType);
if ($ownItem->getRawClassName() == $itemKey) {
$reasons[] = '이미 그 유니크를 가지고 있습니다.';
continue;
}
/*
if (!$ownItem->isBuyable()) {
$reasons[] = '이미 다른 유니크를 가지고 있습니다.';
continue;
}
*/
$availableCnt = $itemList[$itemKey];
$occupiedCnt = $db->queryFirstField('SELECT count(*) FROM general WHERE %b = %s', $itemType, $itemKey);
if ($occupiedCnt >= $availableCnt) {
$reasons[] = '그 유니크는 모두 점유되었습니다.';
continue;
}
$availableItemTypes[] = $itemType;
}
if (!$availableItemTypes) {
rollbackInheritUniqueTrial($general, $itemKey, join(' ', $reasons));
continue;
}
$reasons = [];
$itemType = Util::choiceRandom($availableItemTypes);
$trialStor = KVStorage::getStorage($db, "ut_{$itemKey}"); //혹시 itemKey의 크기가 37이 넘을 수 있을까?
$anyTrials = $trialStor->getAll();
if (!$anyTrials) {
//순서가 꼬였던 모양, 실제 값은 storage를 우선시하자
rollbackInheritUniqueTrial($general, $itemKey, '절차상의 오류입니다.');
continue;
}
//XXX: 정렬할 필요 없지 않나?
usort($anyTrials, function ($lhsTrial, $rhsTrial) {
[,, $lhsAmount] = $lhsTrial;
[,, $rhsAmount] = $rhsTrial;
return $rhsAmount <=> $lhsAmount; //큰 값이 앞에 오도록
});
LogText("선택유니크상태 {$ownerID} {$itemKey}", $anyTrials);
//공동 1등인데 본인이 있을 수도 있다.
[,, $topAmount] = $anyTrials[0];
if ($amount < $topAmount) {
$compAmount = $topAmount / $amount;
if ($compAmount > 2.0) {
$compText = '엄청난 차이로 ';
} else if ($compAmount > 1.2) {
$compText = '큰 차이로 ';
} else if ($compAmount > 1.05) {
$compText = '';
} else {
$compText = '아슬아슬한 차이로 ';
}
rollbackInheritUniqueTrial($general, $itemKey, "{$compText}상위 입찰한 장수가 있습니다.");
continue;
}
//내가 1위다
if ($ownTarget !== null) {
//이미 다른 아이템을 얻기로 되어있다.
continue;
}
$ownTarget = $itemKey;
$ownType = $itemType;
}
unset($itemKey);
unset($itemType);
if ($ownTarget === null) {
return false;
}
if ($justRollback) {
return false;
}
LogText("선택유니크획득{$ownerID}", $ownTarget);
$trialStor = KVStorage::getStorage($db, "ut_{$ownTarget}");
$trialStor->deleteValue("u{$ownerID}");
//rollbackInheritUniqueTrial 과정 때문에 새로 받아와야함
$itemTrials = $general->getAuxVar('inheritUniqueTrial');
unset($itemTrials[$ownTarget]);
$general->setAuxVar('inheritUniqueTrial', $itemTrials);
$nationName = $general->getStaticNation()['name'];
$generalName = $general->getName();
$josaYi = JosaUtil::pick($generalName, '이');
$itemObj = buildItemClass($ownTarget);
$itemName = $itemObj->getName();
$itemRawName = $itemObj->getRawName();
$josaUl = JosaUtil::pick($itemRawName, '을');
$general->setVar($ownType, $ownTarget);
$logger = $general->getLogger();
$logger->pushGeneralActionLog("<C>{$itemName}</>{$josaUl} 습득했습니다!");
$logger->pushGeneralHistoryLog("<C>{$itemName}</>{$josaUl} 습득");
$logger->pushGlobalActionLog("<Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
$logger->pushGlobalHistoryLog("<C><b>【{$acquireType}】</b></><D><b>{$nationName}</b></>의 <Y>{$generalName}</>{$josaYi} <C>{$itemName}</>{$josaUl} 습득했습니다!");
$general->applyDB($db);
return true;
}
function tryUniqueItemLottery(General $general, string $acquireType = '아이템'): bool
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
@@ -1901,22 +1647,14 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
LogText("{$general->getName()}, {$general->getID()} 모든 아이템", $trialCnt); LogText("{$general->getName()}, {$general->getID()} 모든 아이템", $trialCnt);
if ($general->getAuxVar('inheritRandomUnique')) { if ($general->getAuxVar('inheritRandomUnique')) {
$general->setAuxVar('inheritRandomUnique', null); $general->setAuxVar('inheritRandomUnique', null);
$general->increaseInheritancePoint('previous', GameConst::$inheritItemRandomPoint); $general->increaseInheritancePoint(InheritanceKey::previous, GameConst::$inheritItemRandomPoint);
$general->increaseRankVar(RankColumn::inherit_point_spent_dynamic, -GameConst::$inheritItemRandomPoint);
$userLogger = new UserLogger($general->getVar('owner')); $userLogger = new UserLogger($general->getVar('owner'));
$userLogger->push(sprintf("유니크를 얻을 공간이 없어 %d 포인트 반환", GameConst::$inheritItemRandomPoint), "inheritPoint"); $userLogger->push(sprintf("유니크를 얻을 공간이 없어 %d 포인트 반환", GameConst::$inheritItemRandomPoint), "inheritPoint");
} }
tryRollbackInheritUniqueItem($general);
return false; return false;
} }
$inheritUnique = $general->getAuxVar('inheritUniqueTrial');
if ($acquireType != '설문조사' && $inheritUnique && count($inheritUnique) && $availableBuyUnique) {
$trialResult = tryInheritUniqueItem($general, $acquireType);
if ($trialResult) {
return true;
}
}
$scenario = $gameStor->scenario; $scenario = $gameStor->scenario;
$genCount = $db->queryFirstField('SELECT count(*) FROM general WHERE npc<2'); $genCount = $db->queryFirstField('SELECT count(*) FROM general WHERE npc<2');
@@ -1934,11 +1672,12 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
$prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨) $prob = 1 / ($genCount * $itemTypeCnt / 10 / 4); // 건국시 4개(20%) 등장(200명시 20국 정도 됨)
} }
$prob = Util::valueFit($prob, null, 1 / 4); //최대치 감소 $prob *= GameConst::$uniqueTrialCoef;
$prob = Util::valueFit($prob, null, GameConst::$maxUniqueTrialProb); //최대치 감소
$result = false; $result = false;
$prob /= sqrt(2); $prob /= sqrt(7);
$moreProb = pow(2, 1 / 4); $moreProb = pow(10, 1 / 4);
if ($general->getAuxVar('inheritRandomUnique') && $availableBuyUnique) { if ($general->getAuxVar('inheritRandomUnique') && $availableBuyUnique) {
//포인트로 랜덤 유니크 획득 //포인트로 랜덤 유니크 획득
@@ -1946,7 +1685,7 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
} }
foreach (Util::range($maxCnt) as $_idx) { foreach (Util::range($maxCnt) as $_idx) {
if (Util::randBool($prob)) { if ($rng->nextBool($prob)) {
$result = true; $result = true;
break; break;
} }
@@ -1958,7 +1697,7 @@ function tryUniqueItemLottery(General $general, string $acquireType = '아이템
} }
LogText("{$general->getName()}, {$general->getID()} 유니크 성공 {$maxCnt}", $prob); LogText("{$general->getName()}, {$general->getID()} 유니크 성공 {$maxCnt}", $prob);
return giveRandomUniqueItem($general, $acquireType); return giveRandomUniqueItem($rng, $general, $acquireType);
} }
function getAdmin() function getAdmin()
@@ -1988,22 +1727,21 @@ function deleteNation(General $lord, bool $applyDB): array
$logger->pushGlobalHistoryLog("<R><b>【멸망】</b></><D><b>{$nationName}</b></>{$josaUn} <R>멸망</>했습니다."); $logger->pushGlobalHistoryLog("<R><b>【멸망】</b></><D><b>{$nationName}</b></>{$josaUn} <R>멸망</>했습니다.");
$nationGeneralList = General::createGeneralObjListFromDB( $nationGeneralList = General::createObjListFromDB(
$db->queryFirstColumn( $db->queryFirstColumn(
'SELECT `no` FROM general WHERE nation=%i AND no != %i', 'SELECT `no` FROM general WHERE nation=%i AND no != %i',
$nationID, $nationID,
$lordID $lordID
), ),
['npc', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'], ['npc', 'owner', 'gold', 'rice', 'experience', 'explevel', 'dedication', 'dedlevel', 'belong', 'aux'],
1
); );
$nationGeneralList[$lordID] = $lord; $nationGeneralList[$lordID] = $lord;
$nation['generals'] = array_keys($nationGeneralList); $nation['generals'] = array_keys($nationGeneralList);
$nation['aux'] = Json::decode($nation['aux']); $nation['aux'] = Json::decode($nation['aux']);
$nation['msg'] = $nationStor->notice; $nation['msg'] = $nationStor->nationNotice['msg'] ?? '';
$nation['scout_msg'] = $nationStor->scout_msg; $nation['scout_msg'] = $nationStor->scout_msg;
$nation['aux'] += $nationStor->max_power; $nation['aux'] += $nationStor->max_power ?? [];
$nation['history'] = getNationHistoryLogAll($nationID); $nation['history'] = getNationHistoryLogAll($nationID);
$josaYi = JosaUtil::pick($nationName, '이'); $josaYi = JosaUtil::pick($nationName, '이');
@@ -2012,13 +1750,16 @@ function deleteNation(General $lord, bool $applyDB): array
// 전 장수 재야로 // 전 장수 재야로
foreach ($nationGeneralList as $general) { foreach ($nationGeneralList as $general) {
$general->setAuxVar( if ($general->getNPCType() < 2) {
'max_belong', $general->setAuxVar(
max( InheritanceKey::max_belong->value,
$general->getVar('belong'), max(
$general->getAuxVar('max_belong') ?? 0 $general->getVar('belong'),
) $general->getAuxVar(InheritanceKey::max_belong->value) ?? 0
); )
);
}
$general->setVar('belong', 0); $general->setVar('belong', 0);
$general->setVar('troop', 0); $general->setVar('troop', 0);
$general->setVar('officer_level', 0); $general->setVar('officer_level', 0);
@@ -2075,13 +1816,31 @@ function nextRuler(General $general)
//npc or npc유저인 경우 후계 찾기 //npc or npc유저인 경우 후계 찾기
if (!$fiction && $general->getNPCType() > 0) { if (!$fiction && $general->getNPCType() > 0) {
$candidate = $db->queryFirstRow( $rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
'SELECT no,name,officer_level,IF(ABS(affinity-%i)>75,150-ABS(affinity-%i),ABS(affinity-%i)) as npcmatch2 from general where nation=%i and officer_level!=12 and 1 <= npc and npc<=3 order by npcmatch2,rand() LIMIT 1', UniqueConst::$hiddenSeed,
'NextNPCRuler',
$year,
$month,
$general->getID(),
)));
$rawCandidates = $db->query(
'SELECT no,name,officer_level,IF(ABS(affinity-%i)>75,150-ABS(affinity-%i),ABS(affinity-%i)) as npcmatch2 from general where nation=%i and officer_level!=12 and 1 <= npc and npc<=3 order by npcmatch2 asc',
$general->getVar('affinity'), $general->getVar('affinity'),
$general->getVar('affinity'), $general->getVar('affinity'),
$general->getVar('affinity'), $general->getVar('affinity'),
$nationID $nationID
); );
if ($rawCandidates) {
$candidates = [];
$minNPCMatch = $rawCandidates[0]['npcmatch2'];
foreach ($rawCandidates as $candidate) {
if (!$candidate['npcmatch2'] == $minNPCMatch) {
break;
}
$candidates[] = $candidate;
}
$candidate = $rng->choice($candidates);
}
} }
if (!$candidate) { if (!$candidate) {
$candidate = $db->queryFirstRow( $candidate = $db->queryFirstRow(
@@ -2244,7 +2003,7 @@ function calcCityDistance(int $from, int $to, ?array $linkNationList): ?int
* @param $from 기준 도시 코드 * @param $from 기준 도시 코드
* @param $to 대상 도시 코드 * @param $to 대상 도시 코드
* @param $linkNationList 경로에 해당하는 국가 리스트 * @param $linkNationList 경로에 해당하는 국가 리스트
* @return array $dist=>[cityID, $nation] 배열 가장 앞이 가장 가까움 * @return array<int,array{int,int}[]> $dist=>[cityID, $nation] 배열 가장 앞이 가장 가까움
*/ */
function searchDistanceListToDest(int $from, int $to, array $linkNationList) function searchDistanceListToDest(int $from, int $to, array $linkNationList)
{ {
@@ -2405,7 +2164,7 @@ function isNeighbor(int $nation1, int $nation2, bool $includeNoSupply = true)
return false; return false;
} }
function SabotageInjury(array $cityGeneralList, string $reason): int function SabotageInjury(RandUtil $rng, array $cityGeneralList, string $reason): int
{ {
$injuryCount = 0; $injuryCount = 0;
$josaRo = JosaUtil::pick($reason, '로'); $josaRo = JosaUtil::pick($reason, '로');
@@ -2415,12 +2174,14 @@ function SabotageInjury(array $cityGeneralList, string $reason): int
foreach ($cityGeneralList as $general) { foreach ($cityGeneralList as $general) {
/** @var General $general */ /** @var General $general */
if (!Util::randBool(0.3)) { $injuryProb = 0.3;
$injuryProb = $general->onCalcStat($general, 'injuryProb', $injuryProb);
if (!$rng->nextBool($injuryProb)) {
continue; continue;
} }
$general->getLogger()->pushGeneralActionLog($text); $general->getLogger()->pushGeneralActionLog($text);
$general->increaseVarWithLimit('injury', Util::randRangeInt(1, 16), 0, 80); $general->increaseVarWithLimit('injury', $rng->nextRangeInt(1, 16), 0, 80);
$general->multiplyVar('crew', 0.98); $general->multiplyVar('crew', 0.98);
$general->multiplyVar('atmos', 0.98); $general->multiplyVar('atmos', 0.98);
$general->multiplyVar('train', 0.98); $general->multiplyVar('train', 0.98);
@@ -2433,7 +2194,7 @@ function SabotageInjury(array $cityGeneralList, string $reason): int
return $injuryCount; return $injuryCount;
} }
function getRandTurn($term, ?\DateTimeInterface $baseDateTime = null) function getRandTurn(RandUtil $rng, $term, ?\DateTimeInterface $baseDateTime = null)
{ {
if ($baseDateTime === null) { if ($baseDateTime === null) {
$baseDateTime = new \DateTimeImmutable(); $baseDateTime = new \DateTimeImmutable();
@@ -2445,13 +2206,13 @@ function getRandTurn($term, ?\DateTimeInterface $baseDateTime = null)
throw new MustNotBeReachedException(); throw new MustNotBeReachedException();
} }
$randSecond = Util::randRangeInt(0, 60 * $term - 1); $randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수 $randFraction = $rng->nextRangeInt(0, 999999) / 1000000; //6자리 소수
return TimeUtil::format($baseDateTime->add(TimeUtil::secondsToDateInterval($randSecond + $randFraction)), true); return TimeUtil::format($baseDateTime->add(TimeUtil::secondsToDateInterval($randSecond + $randFraction)), true);
} }
function getRandTurn2($term, ?\DateTimeInterface $baseDateTime = null) function getRandTurn2(RandUtil $rng, $term, ?\DateTimeInterface $baseDateTime = null)
{ {
if ($baseDateTime === null) { if ($baseDateTime === null) {
$baseDateTime = new \DateTimeImmutable(); $baseDateTime = new \DateTimeImmutable();
@@ -2460,8 +2221,8 @@ function getRandTurn2($term, ?\DateTimeInterface $baseDateTime = null)
} else { } else {
throw new MustNotBeReachedException(); throw new MustNotBeReachedException();
} }
$randSecond = Util::randRangeInt(0, 60 * $term - 1); $randSecond = $rng->nextRangeInt(0, 60 * $term - 1);
$randFraction = Util::randRangeInt(0, 999999) / 1000000; //6자리 소수 $randFraction = $rng->nextRangeInt(0, 999999) / 1000000; //6자리 소수
return $baseDateTime->sub(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s.u'); return $baseDateTime->sub(TimeUtil::secondsToDateInterval($randSecond + $randFraction))->format('Y-m-d H:i:s.u');
} }
+55 -212
View File
@@ -1,247 +1,90 @@
<?php <?php
namespace sammo; namespace sammo;
function registerAuction() { use sammo\Enums\AuctionType;
function registerAuction(RandUtil $rng)
{
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['startyear', 'year', 'month', 'turnterm']);
$unit = 60 * $admin['turnterm'];
// 장수들 평금,평쌀 // 장수들 평금,평쌀
$general = $db->queryFirstRow('SELECT avg(gold) as gold, avg(rice) as rice,max(gold) as maxgold from general where npc<2'); [$avgGold, $avgRice] = $db->queryFirstList('SELECT avg(gold), avg(rice) from general where npc<2');
$avgGold = Util::valueFit($avgGold, 1000, 20000);
$avgRice = Util::valueFit($avgRice, 1000, 20000);
if($general['gold'] < 1000) { $general['gold'] = 1000; } $neutralAuctionCnt = Util::convertPairArrayToDict($db->queryAllLists(
if($general['gold'] > 20000) { $general['gold'] = 20000; } 'SELECT `type`, count(*) FROM ng_auction WHERE `type` IN %ls AND `host_general_id`=0 GROUP BY `type`',
if($general['rice'] < 1000) { $general['rice'] = 1000; } [AuctionType::BuyRice->value, AuctionType::SellRice->value],
if($general['rice'] > 20000) { $general['rice'] = 20000; } ));
$neutralbuyRiceCnt = $neutralAuctionCnt[AuctionType::BuyRice->value] ?? 0;
$count = $db->queryFirstField('SELECT count(*) FROM auction WHERE type=0 AND no1=0');
$count += 5;
// 판매건 등록 // 판매건 등록
if(Util::randBool(1/$count)) { if ($rng->nextBool(1 / ($neutralbuyRiceCnt + 5))) {
//평균 쌀의 5% ~ 25% //평균 쌀의 5% ~ 25%
$mul = rand() % 5 + 1; $mul = $rng->nextRangeInt(1, 5);
$amount = $general['rice'] / 20 * $mul; $amount = $avgRice / 20 * $mul;
$cost = $general['gold'] / 20 * 0.9 * $mul; $cost = $avgGold / 20 * 0.9 * $mul;
$topv = $amount * 2; $topv = $amount * 2;
if($cost <= $amount*0.8) { $cost = $amount*0.8; } $cost = Util::valueFit($cost, $amount * 0.8, $amount * 1.2);
if($cost >= $amount*1.2) { $cost = $amount*1.2; }
$amount = Util::round($amount, -1); $amount = Util::round($amount, -1);
$cost = Util::round($cost, -1); $cost = Util::round($cost, -1);
$topv = Util::round($topv, -1); $topv = Util::round($topv, -1);
$term = 3 + rand() % 10; $term = $rng->nextRangeInt(3, 12);
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit * $term); $dummyGeneral = AuctionBasicResource::genDummy();
$db->insert('auction', [ AuctionBuyRice::openResourceAuction($dummyGeneral, $amount, $term, $cost, $topv);
'type'=>0,
'no1'=>0,
'name1'=>'ⓝ상인',
'amount'=>$amount,
'cost'=>$cost,
'value'=>$cost,
'topv'=>$topv,
'expire'=>$date
]);
} }
$count = $db->queryFirstField('SELECT count(*) FROM auction WHERE type=1 AND no1=0'); $neutralSellRiceCnt = $neutralAuctionCnt[AuctionType::SellRice->value] ?? 0;
$count += 5;
// 구매건 등록 // 구매건 등록
if(Util::randBool(1/$count)) { if ($rng->nextBool(1 / ($neutralSellRiceCnt + 5))) {
//평균 쌀의 5% ~ 25% //평균 쌀의 5% ~ 25%
$mul = Util::randRangeInt(1, 5); $mul = $rng->nextRangeInt(1, 5);
$amount = $general['rice'] / 20 * $mul; $amount = $avgGold / 20 * $mul;
$cost = $general['gold'] / 20 * 1.1 * $mul; $cost = $avgRice / 20 * 1.1 * $mul;
$topv = $amount * 0.5; $topv = $amount * 2;
if($cost <= $amount*0.8) { $cost = $amount*0.8; } $cost = Util::valueFit($cost, $amount * 0.8, $amount * 1.2);
if($cost >= $amount*1.2) { $cost = $amount*1.2; }
$amount = Util::round($amount, -1); $amount = Util::round($amount, -1);
$cost = Util::round($cost, -1); $cost = Util::round($cost, -1);
$topv = Util::round($topv, -1); $topv = Util::round($topv, -1);
$term = Util::randRangeInt(3, 12); $term = $rng->nextRangeInt(3, 12);
$date = date("Y-m-d H:i:s", strtotime(date("Y-m-d H:i:s")) + $unit * $term); $dummyGeneral = AuctionBasicResource::genDummy();
$db->insert('auction', [ AuctionSellRice::openResourceAuction($dummyGeneral, $amount, $term, $cost, $topv);
'type'=>1,
'no1'=>0,
'name1'=>'ⓝ상인',
'amount'=>$amount,
'cost'=>$cost,
'value'=>$cost,
'topv'=>$topv,
'expire'=>$date
]);
} }
} }
function processAuction() { function processAuction()
{
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$date = TimeUtil::now(); $now = TimeUtil::now();
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']);
$admin = $gameStor->getValues(['year', 'month']); $auctionList = $db->queryAllLists(
'SELECT id, `type` FROM ng_auction WHERE `close_date` <= %s AND finished = 0',
$now
);
foreach($db->query('SELECT * from auction where expire<=%s', $date) as $auction){ if (!$auctionList) {
$josaYi1 = JosaUtil::pick($auction['name1'], '이'); return;
$josaYi2 = JosaUtil::pick($auction['name2'], '이');
// 쌀 처리
if($auction['no2'] == 0) {
// 상인건수가 아닌것만 출력
if($auction['no1'] != 0) {
$traderID = $db->queryFirstField('SELECT no FROM general WHERE no=%i', $auction['no1']);
$logger = new ActionLogger($traderID, 0, $year, $month);
$logger->pushGeneralActionLog("입찰자 부재로 {$auction['no']}번 거래 <M>유찰</>!", ActionLogger::EVENT_PLAIN);
$logger->flush();
$auctionLog = [];
if($auction['type'] == 0) {
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$auctionLog[] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <span class='sell'>판매</span> <M>유찰</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 판매, 그러나 입찰자 부재";
} else {
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$auctionLog[] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <S>구매</> <M>유찰</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 구매, 그러나 입찰자 부재";
}
pushAuctionLog($auctionLog);
}
continue;
}
if($auction['no1'] == 0) {
$trader = [
'no'=>0,
'name'=>'ⓝ상인',
'gold'=>99999,
'rice'=>99999
];
} else {
$trader = $db->queryFirstRow('SELECT no,name,gold,rice from general where no=%i', $auction['no1']);
}
$bidder = $db->queryFirstRow('SELECT no,name,gold,rice from general where no=%i', $auction['no2']);
$traderLogger = new ActionLogger($trader['no'], 0, $year, $month, false);
$bidderLogger = new ActionLogger($bidder['no'], 0, $year, $month, false);
$auctionLog = [];
//판매거래
if($auction['type'] == 0) {
if($auction['amount'] > $trader['rice'] - 1000) {
$gold = Util::round($auction['value'] * 0.01);
$db->update('general', [
'gold'=>Util::valueFit($trader['gold'] - $gold, 0)
], 'no=%i', $trader['no']);
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$josaRo = JosaUtil::pick($auction['value'], '로');
$traderLogger->pushGeneralActionLog("판매자의 군량 부족으로 {$auction['no']}번 거래 <M>유찰</>! 벌금 <C>{$gold}</>", ActionLogger::EVENT_PLAIN);
$bidderLogger->pushGeneralActionLog("판매자의 군량 부족으로 {$auction['no']}번 거래 <M>유찰</>!", ActionLogger::EVENT_PLAIN);
$auctionLog[0] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <span class='sell'>판매</span> <M>유찰</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 판매, <Y>{$auction['name2']}</>{$josaYi2} 금 <C>{$auction['value']}</>{$josaRo} 입찰, 그러나 판매자 군량부족, 벌금 <C>{$gold}</>";
} elseif($auction['value'] > $bidder['gold'] - 1000) {
$gold = Util::round($auction['value'] * 0.01);
$db->update('general', [
'gold'=>Util::valueFit($bidder['gold'] - $gold, 0)
], 'no=%i', $bidder['no']);
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$josaRo = JosaUtil::pick($auction['value'], '로');
$traderLogger->pushGeneralActionLog("입찰자의 자금 부족으로 {$auction['no']}번 거래 <M>유찰</>!", ActionLogger::EVENT_PLAIN);
$bidderLogger->pushGeneralActionLog("입찰자의 자금 부족으로 {$auction['no']}번 거래 <M>유찰</>! 벌금 <C>{$gold}</>", ActionLogger::EVENT_PLAIN);
$auctionLog[0] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <span class='sell'>판매</span> <M>유찰</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 판매, <Y>{$auction['name2']}</>{$josaYi2} 금 <C>{$auction['value']}</>{$josaRo} 입찰, 그러나 입찰자 자금부족, 벌금 <C>{$gold}</>";
} else {
$josaUlGold = JosaUtil::pick($auction['value'], '을');
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$josaRo = JosaUtil::pick($auction['value'], '로');
$traderLogger->pushGeneralActionLog("{$auction['no']}번 거래 <C>성사</>로 쌀 <C>{$auction['amount']}</>{$josaUlRice} 판매, 금 <C>{$auction['value']}</>{$josaUlGold} 획득!", ActionLogger::EVENT_PLAIN);
$bidderLogger->pushGeneralActionLog("{$auction['no']}번 거래 <C>성사</>로 금 <C>{$auction['value']}</>{$josaUlGold} 지불, 쌀 <C>{$auction['amount']}</>{$josaUlRice} 구입!", ActionLogger::EVENT_PLAIN);
$auctionLog[0] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <span class='sell'>판매</span> <C>성사</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 판매, <Y>{$auction['name2']}</>{$josaYi2} 금 <C>{$auction['value']}</>{$josaRo} 구매";
if($auction['value'] >= $auction['amount'] * 2) {
$auctionLog[0] .= " <R>★ 최고가 거래 ★</>";
} elseif($auction['value'] >= $auction['topv']) {
$auctionLog[0] .= " <M>★ 즉시구매가 거래 ★</>";
} elseif($auction['value'] * 2 <= $auction['amount']) {
$auctionLog[0] .= " <R>★ 최저가 거래 ★</>";
}
$db->update('general', [
'gold'=>$db->sqleval('gold + %i', $auction['value']),
'rice'=>$db->sqleval('rice - %i', $auction['amount']),
], 'no=%i', $auction['no1']);
$db->update('general', [
'gold'=>$db->sqleval('gold - %i', $auction['value']),
'rice'=>$db->sqleval('rice + %i', $auction['amount']),
], 'no=%i', $auction['no2']);
}
pushAuctionLog($auctionLog);
//구매거래
} else {
if($auction['amount'] > $bidder['rice'] - 1000) {
$gold = Util::round($auction['value'] * 0.01);
$db->update('general', [
'gold'=>Util::valueFit($bidder['gold'] - $gold, 0)
], 'no=%i', $bidder['no']);
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$josaRo = JosaUtil::pick($auction['value'], '로');
$traderLogger->pushGeneralActionLog("입찰자의 군량 부족으로 {$auction['no']}번 거래 <M>유찰</>!", ActionLogger::EVENT_PLAIN);
$bidderLogger->pushGeneralActionLog("입찰자의 군량 부족으로 {$auction['no']}번 거래 <M>유찰</>! 벌금 <C>{$gold}</>", ActionLogger::EVENT_PLAIN);
$auctionLog[0] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <S>구매</> <M>유찰</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 구매, <Y>{$auction['name2']}</>{$josaYi2} 금 <C>{$auction['value']}</>{$josaRo} 입찰, 그러나 입찰자 군량부족, 벌금 <C>{$gold}</>";
} elseif($auction['value'] > $trader['gold'] - 1000) {
$gold = Util::round($auction['value'] * 0.01);
$db->update('general', [
'gold'=>Util::valueFit($trader['gold'] - $gold, 0)
], 'no=%i', $trader['no']);
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$josaRo = JosaUtil::pick($auction['value'], '로');
$traderLogger->pushGeneralActionLog("구매자의 자금 부족으로 {$auction['no']}번 거래 <M>유찰</>! 벌금 <C>{$gold}</>", ActionLogger::EVENT_PLAIN);
$bidderLogger->pushGeneralActionLog("구매자의 자금 부족으로 {$auction['no']}번 거래 <M>유찰</>!", ActionLogger::EVENT_PLAIN);
$auctionLog[0] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <S>구매</> <M>유찰</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 구매, <Y>{$auction['name2']}</>{$josaYi2} 금 <C>{$auction['value']}</>{$josaRo} 입찰, 그러나 구매자 자금부족, 벌금 <C>{$gold}</>";
} else {
$josaUlGold = JosaUtil::pick($auction['value'], '을');
$josaUlRice = JosaUtil::pick($auction['amount'], '을');
$josaRo = JosaUtil::pick($auction['value'], '로');
$traderLogger->pushGeneralActionLog(
"{$auction['no']}번 거래 <C>성사</>로 금 <C>{$auction['value']}</>{$josaUlGold} 지불, 쌀 <C>{$auction['amount']}</>{$josaUlRice} 구입!", ActionLogger::EVENT_PLAIN
);
$bidderLogger->pushGeneralActionLog("{$auction['no']}번 거래 <C>성사</>로 쌀 <C>{$auction['amount']}</>{$josaUlRice} 판매, 금 <C>{$auction['value']}</>{$josaUlGold} 획득!", ActionLogger::EVENT_PLAIN);
$auctionLog[0] = "<S>◆</>{$admin['year']}{$admin['month']}월, {$auction['no']}번 <S>구매</> <C>성사</> : <Y>{$auction['name1']}</>{$josaYi1} 쌀 <C>{$auction['amount']}</>{$josaUlRice} 구매, <Y>{$auction['name2']}</>{$josaYi2} 금 <C>{$auction['value']}</>{$josaRo} 판매";
if($auction['value'] >= $auction['amount'] * 2) {
$auctionLog[0] .= " <R>★ 최고가 거래 ★</>";
} elseif($auction['value'] * 2 <= $auction['amount']) {
$auctionLog[0] .= " <R>★ 최저가 거래 ★</>";
} elseif($auction['value'] <= $auction['topv']) {
$auctionLog[0] .= " <M>★ 즉시구매가 거래 ★</>";
}
$db->update('general', [
'gold'=>$db->sqleval('gold - %i', $auction['value']),
'rice'=>$db->sqleval('rice + %i', $auction['amount']),
], 'no=%i', $auction['no1']);
$db->update('general', [
'gold'=>$db->sqleval('gold + %i', $auction['value']),
'rice'=>$db->sqleval('rice - %i', $auction['amount']),
], 'no=%i', $auction['no2']);
}
$traderLogger->flush();
$bidderLogger->flush();
pushAuctionLog($auctionLog);
}
$traderLogger->flush();
$bidderLogger->flush();
} }
$db->delete('auction', 'expire <= %s', $date); $dummyGeneral = AuctionBasicResource::genDummy();
foreach ($auctionList as [$auctionID, $rawAuctionType]) {
$auctionType = AuctionType::from($rawAuctionType);
if ($auctionType === AuctionType::BuyRice) {
$auction = new AuctionBuyRice($auctionID, $dummyGeneral);
} else if ($auctionType === AuctionType::SellRice) {
$auction = new AuctionSellRice($auctionID, $dummyGeneral);
} else if ($auctionType === AuctionType::UniqueItem) {
$auction = new AuctionUniqueItem($auctionID, $dummyGeneral);
} else {
throw new \Exception('Unknown auction type');
}
$auction->tryFinish();
}
} }
+7 -5
View File
@@ -213,7 +213,7 @@ function _setGeneralCommand(GeneralCommand $command, array $turnList):void {
$db->update('general_turn', [ $db->update('general_turn', [
'action'=>$commandName, 'action'=>$commandName,
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT), 'arg'=>Json::encode($arg, Json::EMPTY_ARRAY_IS_DICT),
'brief'=>$brief 'brief'=>$brief
], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList); ], 'general_id = %i AND turn_idx IN %li', $generalID, $turnList);
} }
@@ -233,7 +233,7 @@ function _setNationCommand(NationCommand $command, array $turnList):void {
$db->update('nation_turn', [ $db->update('nation_turn', [
'action'=>$commandName, 'action'=>$commandName,
'arg'=>Json::encode($arg, JSON::EMPTY_ARRAY_IS_DICT), 'arg'=>Json::encode($arg, Json::EMPTY_ARRAY_IS_DICT),
'brief'=>$brief 'brief'=>$brief
], 'nation_id = %i AND officer_level = %i AND turn_idx IN %li', $nationID, $officerLevel, $turnList); ], 'nation_id = %i AND officer_level = %i AND turn_idx IN %li', $nationID, $officerLevel, $turnList);
} }
@@ -266,7 +266,7 @@ function checkCommandArg(?array $arg):?string{
/*'string'=>[ /*'string'=>[
'nationName', 'optionText', 'itemType', 'nationType', 'commandType', 'nationName', 'optionText', 'itemType', 'nationType', 'commandType',
],*/ ],*/
'integer'=>[ 'int'=>[
'crewType', 'destGeneralID', 'destCityID', 'destNationID', 'crewType', 'destGeneralID', 'destCityID', 'destNationID',
'amount', 'colorType', 'amount', 'colorType',
'srcArmType', 'destArmType', //숙련전환 전용 'srcArmType', 'destArmType', //숙련전환 전용
@@ -350,7 +350,7 @@ function setGeneralCommand(int $generalID, array $rawTurnList, string $command,
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$env = $gameStor->getAll(); $env = $gameStor->getAll();
$general = General::createGeneralObjFromDB($generalID); $general = General::createObjFromDB($generalID);
try{ try{
$commandObj = buildGeneralCommandClass($command, $general, $env, $arg); $commandObj = buildGeneralCommandClass($command, $general, $env, $arg);
@@ -393,6 +393,7 @@ function setGeneralCommand(int $generalID, array $rawTurnList, string $command,
_setGeneralCommand($commandObj, $turnList); _setGeneralCommand($commandObj, $turnList);
return [ return [
'result'=>true, 'result'=>true,
'brief'=>$commandObj->getBrief(),
'reason'=>'success' 'reason'=>'success'
]; ];
} }
@@ -424,7 +425,7 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$env = $gameStor->getAll(); $env = $gameStor->getAll();
$general = General::createGeneralObjFromDB($generalID); $general = General::createObjFromDB($generalID);
if($general->getVar('officer_level') < 5){ if($general->getVar('officer_level') < 5){
return [ return [
@@ -474,6 +475,7 @@ function setNationCommand(int $generalID, array $turnList, string $command, ?arr
_setNationCommand($commandObj, $turnList); _setNationCommand($commandObj, $turnList);
return [ return [
'result'=>true, 'result'=>true,
'brief'=>$commandObj->getBrief(),
'arg_test'=>true, 'arg_test'=>true,
'reason'=>'success' 'reason'=>'success'
]; ];
+118 -23
View File
@@ -64,6 +64,15 @@ function getNationLevel(int $level) {
][$level]; ][$level];
} }
function convertTournamentType(string $type){
return[
'전력전'=>0,
'통솔전'=>1,
'일기토'=>2,
'설전'=>3,
][$type]??-1;
}
function getGenChar(?string $type) { function getGenChar(?string $type) {
if($type === null){ if($type === null){
return '-'; return '-';
@@ -124,19 +133,19 @@ function getNationType(?string $type) {
} }
function getConnect($con) { function getRefreshScoreText($score) {
if($con < 50) $conname = '안함'; if($score < 50) $scoreName = '안함';
elseif($con < 100) $conname = '무관심'; elseif($score < 100) $scoreName = '무관심';
elseif($con < 200) $conname = '가끔'; elseif($score < 200) $scoreName = '가끔';
elseif($con < 400) $conname = '보통'; elseif($score < 400) $scoreName = '보통';
elseif($con < 800) $conname = '자주'; elseif($score < 800) $scoreName = '자주';
elseif($con < 1600) $conname = '열심'; elseif($score < 1600) $scoreName = '열심';
elseif($con < 3200) $conname = '중독'; elseif($score < 3200) $scoreName = '중독';
elseif($con < 6400) $conname = '폐인'; elseif($score < 6400) $scoreName = '폐인';
elseif($con < 12800) $conname = '경고'; elseif($score < 12800) $scoreName = '경고';
else $conname = '헐...'; else $scoreName = '헐...';
return $conname; return $scoreName;
} }
function getNationType2(?string $type) { function getNationType2(?string $type) {
@@ -247,6 +256,41 @@ function buildItemClass(?string $type):BaseItem{
return $obj; return $obj;
} }
function getScenarioEffectClass(?string $type){
if($type === null || $type === ''){
$type = 'None';
}
static $basePath = __NAMESPACE__.'\\ActionScenarioEffect\\';
$classPath = ($basePath.$type);
if(class_exists($classPath)){
return $classPath;
}
$classPath = ($basePath.'che_'.$type);
if(class_exists($classPath)){
return $classPath;
}
throw new \InvalidArgumentException("{$type}은 시나리오 효과 클래스가 아님");
}
function buildScenarioEffectClass(?string $type):iAction{
static $cache = [];
if($type === null){
$type = 'None';
}
if(key_exists($type, $cache)){
return $cache[$type];
}
$class = getScenarioEffectClass($type);
$obj = new $class();
$cache[$type]= $obj;
return $obj;
}
function getGeneralSpecialDomesticClass(?string $type){ function getGeneralSpecialDomesticClass(?string $type){
if($type === null || $type === ''){ if($type === null || $type === ''){
$type = GameConst::$defaultSpecialDomestic; $type = GameConst::$defaultSpecialDomestic;
@@ -317,6 +361,41 @@ function buildGeneralSpecialWarClass(?string $type):BaseSpecial{
return $obj; return $obj;
} }
function getActionCrewTypeClass(?string $type){
if($type === null || $type === ''){
$type = 'None';
}
static $basePath = __NAMESPACE__.'\\ActionCrewType\\';
$classPath = ($basePath.$type);
if(class_exists($classPath)){
return $classPath;
}
$classPath = ($basePath.'che_'.$type);
if(class_exists($classPath)){
return $classPath;
}
throw new \InvalidArgumentException("{$type}은 올바른 병종 효과가 아님");
}
function buildActionCrewTypeClass(?string $type):iAction{
static $cache = [];
if($type === null){
$type = 'None';
}
if(key_exists($type, $cache)){
return $cache[$type];
}
$class = getActionCrewTypeClass($type);
$obj = new $class();
$cache[$type]= $obj;
return $obj;
}
function getGeneralCommandClass(?string $type){ function getGeneralCommandClass(?string $type){
if($type === null || $type === ''){ if($type === null || $type === ''){
$type = '휴식'; $type = '휴식';
@@ -396,10 +475,10 @@ function getGeneralPoolClass(string $type){
* @param null|string $prefix * @param null|string $prefix
* @return AbsGeneralPool[] * @return AbsGeneralPool[]
*/ */
function pickGeneralFromPool(\MeekroDB $db, int $owner, int $pickCnt, ?string $prefix=null):array{ function pickGeneralFromPool(\MeekroDB $db, RandUtil $rng, int $owner, int $pickCnt, ?string $prefix=null):array{
/** @var AbsGeneralPool */ /** @var AbsGeneralPool */
$class = getGeneralPoolClass(GameConst::$targetGeneralPool); $class = getGeneralPoolClass(GameConst::$targetGeneralPool);
return $class::pickGeneralFromPool($db, $owner, $pickCnt, $prefix); return $class::pickGeneralFromPool($db, $rng, $owner, $pickCnt, $prefix);
} }
function countPureGeneralFromRawList(?array $rawGeneralList=null):int{ function countPureGeneralFromRawList(?array $rawGeneralList=null):int{
@@ -533,6 +612,8 @@ function getExpLevel($experience) {
$level = Util::toInt(sqrt($experience/10)); $level = Util::toInt(sqrt($experience/10));
} }
$level = Util::clamp($level, 0, GameConst::$maxLevel);
return $level; return $level;
} }
@@ -657,7 +738,7 @@ function getDexCall(int $dex) : string {
function getDexLevel(int $dex) : int { function getDexLevel(int $dex) : int {
if($dex < 0){ if($dex < 0){
throw new \InvalidArgumentException(); return 0;
} }
$retVal = 0; $retVal = 0;
@@ -692,21 +773,35 @@ function isConsumable(?string $item) : bool{
return $itemClass->isConsumable(); return $itemClass->isConsumable();
} }
function getNameColor(int $npcType):?string{ function getNPCColor(int $npc): ?string{
if($npcType >= 2){ if ($npc == 1) {
return 'cyan';
}
if($npcType == 1){
return 'skyblue'; return 'skyblue';
} }
if ($npc == 4){
return 'deepskyblue';
}
if ($npc == 5){
return 'darkcyan';
}
if ($npc == 6){
return 'mediumaquamarine';
}
if ($npc > 1) {
return 'cyan';
}
return null; return null;
} }
function getColoredName(string $name, int $npcType):string{
$color = getNameColor($npcType); function formatName(string $name, int $npc): string
{
$color = getNPCColor($npc);
if($color === null){ if($color === null){
return $name; return $name;
} }
return "<span style='color:{$color}'>{$name}</span>";
return "<span style='color:{$color}'>$name</span>";
} }
function ConvertLog(?string $str, $type=1) : string { function ConvertLog(?string $str, $type=1) : string {
+112 -364
View File
@@ -2,7 +2,11 @@
namespace sammo; namespace sammo;
use Monolog\Logger; use sammo\DTO\AuctionInfo;
use sammo\Enums\AuctionType;
use sammo\Enums\EventTarget;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
/** /**
* 게임 룰에 해당하는 함수 모음 * 게임 룰에 해당하는 함수 모음
@@ -181,27 +185,6 @@ function updateGeneralNumber()
refreshNationStaticInfo(); refreshNationStaticInfo();
} }
function updateYearly()
{
//통계
checkStatistic();
}
//관직 변경 해제
function updateQuaterly()
{
$db = DB::db();
//천도 제한 해제, 관직 변경 제한 해제
$db->update('nation', [
'chief_set' => 0,
], true);
//관직 변경 제한 해제
$db->update('city', [
'officer_set' => 0,
], true);
}
// 벌점 감소와 건국제한-1 전턴제한-1 외교제한-1, 1달마다 실행, 병사 있는 장수의 군량 감소, 수입비율 조정 // 벌점 감소와 건국제한-1 전턴제한-1 외교제한-1, 1달마다 실행, 병사 있는 장수의 군량 감소, 수입비율 조정
function preUpdateMonthly() function preUpdateMonthly()
{ {
@@ -217,62 +200,12 @@ function preUpdateMonthly()
$admin = $gameStor->getValues(['startyear', 'year', 'month']); $admin = $gameStor->getValues(['startyear', 'year', 'month']);
$logger = new ActionLogger(0, 0, $admin['year'], $admin['month']);
//보급선 체크
checkSupply();
//미보급도시 10% 감소
$db->update('city', [
'pop' => $db->sqleval('pop * 0.9'),
'trust' => $db->sqleval('trust * 0.9'),
'agri' => $db->sqleval('agri * 0.9'),
'comm' => $db->sqleval('comm * 0.9'),
'secu' => $db->sqleval('secu * 0.9'),
'def' => $db->sqleval('def * 0.9'),
'wall' => $db->sqleval('wall * 0.9'),
], 'supply = 0');
//미보급도시 장수 병 훈 사 5%감소
//NOTE: update inner join도 가능하지만, meekrodb 기준으로 깔끔하게.
$unsuppliedCities = $db->query('SELECT city, nation, trust, name FROM city WHERE supply = 0');
foreach (Util::arrayGroupBy($unsuppliedCities, 'nation') as $nationID => $cityList) {
$cityIDList = Util::squeezeFromArray($cityList, 'city');
$db->update('general', [
'crew' => $db->sqleval('crew*0.95'),
'atmos' => $db->sqleval('atmos*0.95'),
'train' => $db->sqleval('train*0.95'),
], 'city IN %li AND nation = %i', $cityIDList, $nationID);
}
//민심30이하 공백지 처리
$lostCities = [];
foreach ($unsuppliedCities as $unsuppliedCity) {
if ($unsuppliedCity['trust'] >= 30) {
continue;
}
$lostCities[$unsuppliedCity['city']] = $unsuppliedCity;
}
if ($lostCities) {
foreach ($lostCities as $lostCity) {
$josaYi = JosaUtil::pick($lostCity['name'], '이');
$logger->pushGlobalHistoryLog("<R><b>【고립】</b></><G><b>{$lostCity['name']}</b></>{$josaYi} 보급이 끊겨 <R>미지배</> 도시가 되었습니다.");
}
$db->update('general', [
'officer_level' => 1,
'officer_city' => 0
], 'officer_city IN %li', array_keys($lostCities));
$db->update('city', [
'nation' => 0,
'officer_set' => 0,
'conflict' => '{}',
'term' => 0,
'front' => 0
], 'city IN %li', array_keys($lostCities));
}
//접률감소, 건국제한-1 //접률감소, 건국제한-1
$db->update('general_access_log', [
'refresh_score_total' => $db->sqleval('floor(refresh_score_total*0.99)'),
], true);
$db->update('general', [ $db->update('general', [
'connect' => $db->sqleval('floor(connect*0.99)'),
'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'), 'makelimit' => $db->sqleval('greatest(0, makelimit - 1)'),
], true); ], true);
//전략제한-1, 외교제한-1, 세율동기화 //전략제한-1, 외교제한-1, 세율동기화
@@ -282,18 +215,10 @@ function preUpdateMonthly()
'rate_tmp' => $db->sqleval('rate') 'rate_tmp' => $db->sqleval('rate')
], true); ], true);
//도시훈사 180년 60, 220년 87, 240년 100
$rate = Util::round(($admin['year'] - $admin['startyear']) / 1.5) + 60;
if ($rate > 100) $rate = 100;
// 20 ~ 140원 // 20 ~ 140원
$develcost = ($admin['year'] - $admin['startyear'] + 10) * 2; $develcost = ($admin['year'] - $admin['startyear'] + 10) * 2;
$gameStor->city_rate = $rate;
$gameStor->develcost = $develcost; $gameStor->develcost = $develcost;
//매달 사망자 수입 결산
processWarIncome();
//계략, 전쟁표시 해제 //계략, 전쟁표시 해제
$db->update('city', [ $db->update('city', [
'state' => $db->sqleval(<<<EOD 'state' => $db->sqleval(<<<EOD
@@ -332,7 +257,7 @@ EOD),
} }
// 외교 로그처리, 외교 상태 처리 // 외교 로그처리, 외교 상태 처리
function postUpdateMonthly() function postUpdateMonthly(RandUtil $rng)
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
@@ -371,14 +296,13 @@ function postUpdateMonthly()
sum(pop)*sum(pop+agri+comm+secu+wall+def)/sum(pop_max+agri_max+comm_max+secu_max+wall_max+def_max)/100 sum(pop)*sum(pop+agri+comm+secu+wall+def)/sum(pop_max+agri_max+comm_max+secu_max+wall_max+def_max)/100
) from city where nation=A.nation and supply=1 ) from city where nation=A.nation and supply=1
)) ))
+(select SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)*2 + (SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/2) +(select SUM((ra.value + 1000)/(rb.value + 1000)*(CASE WHEN g.`npc` < 2 THEN 1.2 ELSE 1 END)*(CASE WHEN g.`leadership` >= 40 THEN g.`leadership` ELSE 0 END)*2 + (SQRT(g.intel * g.strength) * 2 + g.leadership / 2)/2)
FROM general AS g FROM general AS g
LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = \'killcrew_person\' LEFT JOIN `rank_data` AS ra ON g.`no` = ra.general_id AND ra.`type` = \'killcrew_person\'
LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = \'deathcrew_person\' LEFT JOIN `rank_data` AS rb ON g.`no` = rb.general_id AND rb.`type` = \'deathcrew_person\'
WHERE g.nation = A.nation) WHERE g.nation = A.nation)
+(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation) +(select round(sum(dex1+dex2+dex3+dex4+dex5)/1000) from general where nation=A.nation)
+(select round(sum(experience+dedication)/100) from general where nation=A.nation) +(select round(sum(experience+dedication)/100) from general where nation=A.nation)
+(select round(avg(connect)) from general where nation=A.nation)
)/10) )/10)
as power, as power,
(select sum(crew) from general where nation=A.nation) as totalCrew (select sum(crew) from general where nation=A.nation) as totalCrew
@@ -395,7 +319,7 @@ function postUpdateMonthly()
//약간의 랜덤치 부여 (95% ~ 105%) //약간의 랜덤치 부여 (95% ~ 105%)
$nation['power'] = Util::round($nation['power'] * (rand() % 101 + 950) / 1000); $nation['power'] = Util::round($nation['power'] * $rng->nextRange(0.95, 1.05));
$powerValues['maxPower'] = max($powerValues['maxPower'] ?? 0, $nation['power']); $powerValues['maxPower'] = max($powerValues['maxPower'] ?? 0, $nation['power']);
$powerValues['maxCrew'] = max($powerValues['maxCrew'] ?? 0, Util::toInt($nation['totalCrew'])); $powerValues['maxCrew'] = max($powerValues['maxCrew'] ?? 0, Util::toInt($nation['totalCrew']));
@@ -484,12 +408,12 @@ function postUpdateMonthly()
$availableWarSettingCnt = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'available_war_setting_cnt'); $availableWarSettingCnt = KVStorage::getValuesFromInterNamespace($db, 'nation_env', 'available_war_setting_cnt');
foreach ($nations as $nation) { foreach ($nations as $nation) {
$nationID = $nation['nation']; $nationID = $nation['nation'];
if(!key_exists($nationID, $availableWarSettingCnt)){ if (!key_exists($nationID, $availableWarSettingCnt)) {
$availableWarSettingCnt[$nationID] = 0; $availableWarSettingCnt[$nationID] = 0;
} }
} }
foreach($availableWarSettingCnt as $nationID=>$cnt){ foreach ($availableWarSettingCnt as $nationID => $cnt) {
if($cnt >= GameConst::$maxAvailableWarSettingCnt){ if ($cnt >= GameConst::$maxAvailableWarSettingCnt) {
continue; continue;
} }
$cnt = Util::valueFit($cnt + GameConst::$incAvailableWarSettingCnt, 0, GameConst::$maxAvailableWarSettingCnt); $cnt = Util::valueFit($cnt + GameConst::$incAvailableWarSettingCnt, 0, GameConst::$maxAvailableWarSettingCnt);
@@ -498,18 +422,16 @@ function postUpdateMonthly()
//초반이후 방랑군 자동 해체 //초반이후 방랑군 자동 해체
if ($admin['year'] >= $admin['startyear'] + 2) { if ($admin['year'] >= $admin['startyear'] + 2) {
checkWander(); checkWander($rng);
} }
// 작위 업데이트
updateNationState();
updateGeneralNumber(); updateGeneralNumber();
refreshNationStaticInfo(); refreshNationStaticInfo();
// 천통여부 검사 // 천통여부 검사
checkEmperior(); checkEmperior();
//토너먼트 개시 //토너먼트 개시
triggerTournament(); triggerTournament($rng);
// 시스템 거래건 등록 // 시스템 거래건 등록
registerAuction(); registerAuction($rng);
//전방설정 //전방설정
foreach (getAllNationStaticInfo() as $nation) { foreach (getAllNationStaticInfo() as $nation) {
if ($nation['level'] <= 0) { if ($nation['level'] <= 0) {
@@ -520,21 +442,21 @@ function postUpdateMonthly()
} }
function checkWander() function checkWander(RandUtil $rng)
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month']); $admin = $gameStor->getValues(['year', 'month', 'init_year', 'init_month']);
$wanderers = $db->queryFirstColumn('SELECT general.`no` FROM general LEFT JOIN nation ON general.nation = nation.nation WHERE nation.`level` = 0 AND general.`officer_level` = 12'); $wanderers = $db->queryFirstColumn('SELECT general.`no` FROM general LEFT JOIN nation ON general.nation = nation.nation WHERE nation.`level` = 0 AND general.`officer_level` = 12');
foreach (General::createGeneralObjListFromDB($wanderers) as $wanderer) { foreach (General::createObjListFromDB($wanderers) as $wanderer) {
$wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin); $wanderCmd = buildGeneralCommandClass('che_해산', $wanderer, $admin);
if ($wanderCmd->hasFullConditionMet()) { if ($wanderCmd->hasFullConditionMet()) {
$logger = $wanderer->getLogger(); $logger = $wanderer->getLogger();
$logger->pushGeneralActionLog('초반 제한후 방랑군은 자동 해산됩니다.', ActionLogger::PLAIN); $logger->pushGeneralActionLog('초반 제한후 방랑군은 자동 해산됩니다.', ActionLogger::PLAIN);
$wanderCmd->run(); $wanderCmd->run($rng);
$wanderCmd->setNextAvailable(); $wanderCmd->setNextAvailable();
} }
} }
@@ -544,218 +466,6 @@ function checkWander()
} }
} }
function updateNationState()
{
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$history = array();
$admin = $gameStor->getValues(['killturn', 'year', 'month', 'fiction', 'startyear', 'show_img_level', 'turnterm', 'turntime']);
$assemblerCnts = [];
foreach ($db->queryAllLists('SELECT nation,count(no) FROM general WHERE npc = 5 GROUP BY nation') as [$nationID, $assemblerCnt]) {
$assemblerCnts[$nationID] = $assemblerCnt;
};
foreach ($db->query('SELECT nation,name,level,tech,aux FROM nation') as $nation) {
//TODO: level이 진관수이소중대특 체계를 벗어날 수 있음
$citycount = $db->queryFirstField('SELECT count(*) FROM city WHERE nation=%i AND level>=4', $nation['nation']);
if ($citycount == 0) {
$nationlevel = 0; // 방랑군
} elseif ($citycount == 1) {
$nationlevel = 1; // 호족
} elseif ($citycount <= 4) {
$nationlevel = 2; // 군벌
} elseif ($citycount <= 7) {
$nationlevel = 3; // 주자사
} elseif ($citycount <= 10) {
$nationlevel = 4; // 주목
} elseif ($citycount <= 15) {
$nationlevel = 5; // 공
} elseif ($citycount <= 20) {
$nationlevel = 6; // 왕
} else {
$nationlevel = 7; // 황제
}
if ($nationlevel > $nation['level']) {
$levelDiff = $nationlevel - $nation['level'];
$oldLevel = $nation['level'];
$nation['level'] = $nationlevel;
$updateVals = [
'level' => $nationlevel,
'gold' => $db->sqleval('gold + %i', $nationlevel * 1000),
'rice' => $db->sqleval('rice + %i', $nationlevel * 1000),
];
switch ($nationlevel) {
case 7:
$josaUl = JosaUtil::pick(getNationLevel($nationlevel), '을');
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭하였습니다.";
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}{$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>{$josaUl} 자칭"]);
$auxVal = Json::decode($nation['aux']);
$auxVal['can_국기변경'] = 1;
$auxVal['can_국호변경'] = 1;
$updateVals['aux'] = Json::encode($auxVal);
break;
case 6:
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극하였습니다.";
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}{$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 등극"]);
break;
case 5:
case 4:
case 3:
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명되었습니다.";
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}{$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>에 임명됨"]);
break;
case 2:
$history[] = "<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【작위】</b></><D><b>{$nation['name']}</b></>의 군주가 독립하여 <Y>" . getNationLevel($nationlevel) . "</>로 나섰습니다.";
pushNationHistoryLog($nation['nation'], ["<C>●</>{$admin['year']}{$admin['month']}월:<D><b>{$nation['name']}</b></>의 군주가 <Y>" . getNationLevel($nationlevel) . "</>로 나서다"]);
break;
}
$db->update('nation', $updateVals, 'nation=%i', $nation['nation']);
$turnRows = [];
foreach (Util::range(getNationChiefLevel($nation['level']), 12) as $chiefLevel) {
foreach (Util::range(GameConst::$maxChiefTurn) as $turnIdx) {
$turnRows[] = [
'nation_id' => $nation['nation'],
'officer_level' => $chiefLevel,
'turn_idx' => $turnIdx,
'action' => '휴식',
'arg' => null,
'brief' => '휴식'
];
}
}
$db->insertIgnore('nation_turn', $turnRows);
if ($levelDiff) {
//유니크 아이템 하나 돌리자
$targetKillTurn = $admin['killturn'];
$targetKillTurn -= 24 * 60 / $admin['turnterm'];
$nationGenIDList = $db->queryFirstColumn(
'SELECT no FROM general WHERE nation = %i AND killturn >= %i AND npc < 2',
$nation['nation'],
$targetKillTurn
);
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2);
$chiefID = null;
$uniqueLotteryWeightList = [];
[$startYear, $year] = $gameStor->getValuesAsArray(['startyear', 'year']);
$relYear = $year - $startYear;
$maxTrialCountByYear = 1;
foreach (GameConst::$maxUniqueItemLimit as $tmpVals) {
[$targetYear, $targetTrialCnt] = $tmpVals;
if ($relYear < $targetYear) {
break;
}
$maxTrialCountByYear = $targetTrialCnt;
}
foreach ($nationGenList as $nationGen) {
if ($nationGen->getVar('officer_level') == 12) {
$chiefID = $nationGen->getID();
}
$trialCnt = min($maxTrialCountByYear, count(GameConst::$allItems));
foreach ($nationGen->getItems() as $item) {
if (!$item->isBuyable()) {
$trialCnt -= 1;
}
}
if ($trialCnt <= 0) {
continue;
}
$score = $nationGen->getVar('belong') + 5;
if ($nationGen->getVar('officer_level') == 12) {
$score += 100; //NOTE: 꼬우면 군주하세요.
} else if ($nationGen->getVar('officer_level') == 11) {
$score += 50;
} else if ($nationGen->getVar('officer_level') > 4) {
$score += 35;
}
$score *= $trialCnt;
$uniqueLotteryWeightList[$nationGen->getID()] = [$nationGen, $score];
}
foreach (Util::range($levelDiff) as $idx) {
if (!$uniqueLotteryWeightList) {
break;
}
/** @var General */
$winnerObj = Util::choiceRandomUsingWeightPair($uniqueLotteryWeightList);
unset($uniqueLotteryWeightList[$winnerObj->getID()]);
giveRandomUniqueItem($winnerObj, '작위보상');
$winnerObj->applyDB($db);
}
if ($chiefID) {
$chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], 2);
$chiefObj->increaseInheritancePoint('unifier', 250 * $levelDiff);
$chiefObj->applyDB($db);
}
}
}
$assemblerCnt = $assemblerCnts[$nation['nation']] ?? 0;
$maxAssemblerCnt = [
1 => 0,
2 => 1,
3 => 3,
4 => 4,
5 => 6,
6 => 7,
7 => 9
][$nationlevel] ?? 0;
if ($assemblerCnt < $maxAssemblerCnt) {
$lastAssemblerID = $gameStor->assembler_id ?? 0;
while ($assemblerCnt < $maxAssemblerCnt) {
$lastAssemblerID += 1;
$npcObj = new Scenario\GeneralBuilder(
sprintf('부대장%4d', $lastAssemblerID),
false,
null,
$nation['nation']
);
$npcObj->setAffinity(999)->setStat(10, 10, 10)
->setSpecialSingle('척사')->setEgo('che_은둔')
->setKillturn(70)->setGoldRice(0, 0)
->setNPCType(5)->fillRemainSpecAsZero($admin);
$npcObj->build($admin);
$npcID = $npcObj->getGeneralID();
$db->insert('troop', [
'troop_leader' => $npcID,
'name' => $npcObj->getGeneralName(),
'nation' => $nation['nation'],
]);
$db->update('general', [
'troop' => $npcID
], 'no=%i', $npcID);
$cmd = buildGeneralCommandClass('che_집합', General::createGeneralObjFromDB($npcID), $admin);
_setGeneralCommand($cmd, iterator_to_array(Util::range(GameConst::$maxTurn)));
$assemblerCnt += 1;
$gameStor->assembler_id = $lastAssemblerID;
}
}
}
pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
}
function checkStatistic() function checkStatistic()
{ {
$db = DB::db(); $db = DB::db();
@@ -988,7 +698,7 @@ function checkEmperior()
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'isunited', 'conlimit']); $admin = $gameStor->getValues(['year', 'month', 'isunited', 'refreshLimit']);
if ($admin['isunited'] != 0) { if ($admin['isunited'] != 0) {
return; return;
} }
@@ -1022,19 +732,35 @@ function checkEmperior()
$nationLogger = new ActionLogger(0, $nationID, $admin['year'], $admin['month']); $nationLogger = new ActionLogger(0, $nationID, $admin['year'], $admin['month']);
$nationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일"); $nationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaYi} 전토를 통일");
foreach (General::createGeneralObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc < 2')) as $genObj) { /** @var int[] */
$auctionList = $db->queryFirstColumn(
'SELECT `id` FROM `ng_auction` WHERE `type` = %s AND `finished` = 0 ORDER BY `close_date` ASC',
AuctionType::UniqueItem->value
);
foreach($auctionList as $auctionID){
$auction = new AuctionUniqueItem($auctionID, new DummyGeneral(true));
$auction->closeAuction(true);
}
$inheritPointManager = InheritancePointManager::getInstance();
$allUserGenerals = General::createObjListFromDB($db->queryFirstColumn('SELECT `no` FROM general WHERE npc < 2'));
foreach ($allUserGenerals as $genObj) {
if ($genObj->getNationID() == $nationID) { if ($genObj->getNationID() == $nationID) {
if ($genObj->getVar('officer_level') > 4) { if ($genObj->getVar('officer_level') > 4) {
$genObj->increaseInheritancePoint('unifier', 2000); $genObj->increaseInheritancePoint(InheritanceKey::unifier, 2000);
}; };
} }
$genObj->mergeTotalInheritancePoint(true); }
applyInheritanceUser($genObj->getVar('owner'));
$genObj->clearInheritancePoint(); TurnExecutionHelper::runEventHandler($db, $gameStor, EventTarget::United);
foreach ($allUserGenerals as $genObj) {
$inheritPointManager->mergeTotalInheritancePoint($genObj);
$inheritPointManager->applyInheritanceUser($genObj->getVar('owner'));
} }
$gameStor->isunited = 2; $gameStor->isunited = 2;
$gameStor->conlimit = $gameStor->conlimit * 100; $gameStor->refreshLimit = $gameStor->refreshLimit * 100;
foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) { foreach ($db->queryFirstColumn('SELECT no FROM general WHERE npc<2 AND age>=%i', GameConst::$minPushHallAge) as $hallGeneralNo) {
CheckHall($hallGeneralNo); CheckHall($hallGeneralNo);
@@ -1046,7 +772,7 @@ function checkEmperior()
$chiefs = Util::convertArrayToDict( $chiefs = Util::convertArrayToDict(
$db->query( $db->query(
'SELECT no,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5', 'SELECT no,npc,name,picture,belong,officer_level FROM general WHERE nation=%i AND officer_level >= 5',
$nationID $nationID
), ),
'officer_level' 'officer_level'
@@ -1099,9 +825,9 @@ function checkEmperior()
$nation = $nation; $nation = $nation;
$nation['generals'] = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=%i', $nation['nation']); $nation['generals'] = $db->queryFirstColumn('SELECT `no` FROM general WHERE nation=%i', $nation['nation']);
$nation['aux'] = Json::decode($nation['aux']); $nation['aux'] = Json::decode($nation['aux']);
$nation['msg'] = $nationStor->notice; $nation['msg'] = $nationStor->nationNotice['msg'] ?? '';;
$nation['scout_msg'] = $nationStor->scout_msg; $nation['scout_msg'] = $nationStor->scout_msg;
$nation['aux'] += $nationStor->max_power; $nation['aux'] += $nationStor->max_power ?? [];
$nation['history'] = getNationHistoryLogAll($nation['nation']); $nation['history'] = getNationHistoryLogAll($nation['nation']);
storeOldGenerals(0, $admin['year'], $admin['month']); storeOldGenerals(0, $admin['year'], $admin['month']);
@@ -1173,66 +899,88 @@ function checkEmperior()
'tiger' => $tigerstr, 'tiger' => $tigerstr,
'eagle' => $eaglestr, 'eagle' => $eaglestr,
'gen' => $gen, 'gen' => $gen,
'history' => JSON::encode($nationHistory), 'history' => Json::encode($nationHistory),
'aux' => $statGeneral['aux'] 'aux' => $statGeneral['aux']
]); ]);
$history = ["<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【통일】</b></><D><b>{$nation['name']}</b></>{$josaYi} 전토를 통일하였습니다."]; $hiddenSeed = UniqueConst::$hiddenSeed;
$history = ["<C>●</>{$admin['year']}{$admin['month']}월:<Y><b>【통일】</b></><D><b>{$nation['name']}</b></>{$josaYi} 전토를 통일하였습니다. <span class='hidden_but_copyable'>(서버시드: {$hiddenSeed})</span>"];
pushGlobalHistoryLog($history, $admin['year'], $admin['month']); pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
//연감 월결산 //연감 월결산
LogHistory(); LogHistory();
}
function applyInheritanceUser(int $userID, bool $isRebirth = false): float $availableInvaderGame = false;
{ foreach(CityConst::all() as $city){
//FIXME: 은퇴, 사망, 천통 시점에 바로 반영한다면 여기가 아니라 general class로 이동하는 것이 옳음 if($city->level == 4){
//또한 굳이 merge, apply, clean 3단계를 거쳐야 할 이유도 없음 $availableInvaderGame = true;
$rebirthDegraded = [ break;
'dex' => 0.5, }
];
$inheritStor = KVStorage::getStorage(DB::db(), "inheritance_{$userID}");
$totalPoint = 0;
$allPoints = $inheritStor->getAll();
if (!$allPoints || count($allPoints) == 0) {
//비었으므로 리셋 안함
return 0;
} }
if (count($allPoints) == 1 && key_exists('previous', $allPoints)) { if($availableInvaderGame){
//이미 리셋되었으므로 리셋 안함 $invaderMsgCnt = 2;
return $allPoints['previous'][0]; foreach(range(12, 5, -1) as $chiefLevel){
} if(!key_exists($chiefLevel, $chiefs)){
continue;
$userLogger = new UserLogger($userID); }
$targetChief = $chiefs[$chiefLevel];
$previousPoint = ($allPoints['previous'] ?? [0, 0])[0]; if($targetChief['npc'] >= 2){
continue;
foreach ($allPoints as $key => [$value,]) { }
if ($isRebirth && key_exists($key, $rebirthDegraded)) { $invaderMsgs = RaiseInvaderMessage::buildRaiseInvaderMessage($targetChief['no']);
$value *= $rebirthDegraded[$key]; foreach($invaderMsgs as $invaderMsg){
$invaderMsg->send();
}
$invaderMsgCnt--;
if($invaderMsgCnt <= 0){
break;
}
} }
$keyText = General::INHERITANCE_KEY[$key][2];
$userLogger->push("{$keyText} 포인트 {$value} 증가", "inheritPoint");
$totalPoint += $value;
} }
$totalPoint = Util::toInt($totalPoint);
$userLogger->push("포인트 {$previousPoint} => {$totalPoint}", "inheritPoint");
$userLogger->flush();
$inheritStor->resetValues();
$inheritStor->setValue('previous', [$totalPoint, null]);
return $totalPoint;
} }
function updateMaxDomesticCritical(General $general, $score) function updateMaxDomesticCritical(General $general, $score)
{ {
$maxDomesticCritical = $general->getAuxVar('max_domestic_critical') ?? 0; $maxDomesticCritical = $general->getAuxVar(InheritanceKey::max_domestic_critical->value) ?? 0;
$maxDomesticCritical += $score / 2; $maxDomesticCritical += $score / 2;
$general->setAuxVar('max_domestic_critical', $maxDomesticCritical); $general->setAuxVar(InheritanceKey::max_domestic_critical->value, $maxDomesticCritical);
$oldMaxDomesticCritical = $general->getInheritancePoint('max_domestic_critical'); $oldMaxDomesticCritical = $general->getInheritancePoint(InheritanceKey::max_domestic_critical);
if ($maxDomesticCritical > $oldMaxDomesticCritical) { if ($maxDomesticCritical > $oldMaxDomesticCritical) {
$general->setInheritancePoint('max_domestic_critical', $maxDomesticCritical); $general->setInheritancePoint(InheritanceKey::max_domestic_critical, $maxDomesticCritical);
} }
} }
function genGenericUniqueRNG(int $year, int $month, int $generalID, ?string $reason = null): RandUtil
{
if($reason){
return new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'unique',
$year,
$month,
$generalID,
$reason
)));
}
return new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'unique',
$year,
$month,
$generalID
)));
}
function genGenericUniqueRNGFromGeneral(General $general, string $reason): RandUtil
{
$logger = $general->getLogger();
if (!$logger) {
throw new \Exception('정식 초기화된 객체가 아닙니다.');
}
$year = $logger->getYear();
$month = $logger->getMonth();
$generalID = $general->getID();
return genGenericUniqueRNG($year, $month, $generalID, $reason);
}
+39 -23
View File
@@ -90,8 +90,8 @@ function pushAuctionLog($log) {
pushRawFileLog(__DIR__."/logs/".UniqueConst::$serverID."/_auctionlog.txt", $log); pushRawFileLog(__DIR__."/logs/".UniqueConst::$serverID."/_auctionlog.txt", $log);
} }
function getAuctionLogRecent(int $count) { function getAuctionLogRecent(int $count): array {
return join('<br>', array_reverse(getFormattedFileLogRecent(__DIR__."/logs/".UniqueConst::$serverID."/_auctionlog.txt", $count, 300))); return array_reverse(getRawFileLogRecent(__DIR__."/logs/".UniqueConst::$serverID."/_auctionlog.txt", $count, 300));
} }
//DB-based //DB-based
@@ -254,6 +254,7 @@ function pushGeneralHistoryLog(int $generalID, ?array $history, $year=null, $mon
} }
/** @deprecated */
function getGeneralHistoryLogAll(int $generalID):array { function getGeneralHistoryLogAll(int $generalID):array {
$db = DB::db(); $db = DB::db();
@@ -263,6 +264,15 @@ function getGeneralHistoryLogAll(int $generalID):array {
); );
} }
function getGeneralHistoryLogWithLogID(int $generalID):array {
$db = DB::db();
return Util::convertPairArrayToDict($db->queryAllLists(
'SELECT `id`, `text` from general_record WHERE general_id = %i AND log_type = "history" order by id desc',
$generalID
));
}
function pushNationHistoryLog(int $nationID, ?array $history, ?int $year=null, ?int $month=null) { function pushNationHistoryLog(int $nationID, ?array $history, ?int $year=null, ?int $month=null) {
if(!$history){ if(!$history){
@@ -371,10 +381,11 @@ function getGlobalActionLogWithDate(int $year, int $month):array {
return $texts; return $texts;
} }
function LogHistory($isFirst=0) { function getCurrentHistory($isFirst=false) {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$obj = $gameStor->getValues(['startyear', 'year', 'month']); [$startYear, $year, $month]= $gameStor->getValuesAsArray(['startyear', 'year', 'month']);
$yearMonth = Util::joinYearMonth($year, $month);
$map = getWorldMap([ $map = getWorldMap([
'year'=>null, 'year'=>null,
@@ -384,21 +395,14 @@ function LogHistory($isFirst=0) {
'aux'=>[] 'aux'=>[]
]); ]);
if($isFirst){
$map['month'] = $obj['month']; $yearMonth -= 1;
$map['year'] = $obj['year'];
$map['startYear'] = $obj['startyear'];
if($isFirst == 1){
$map['month'] -= 1;
if($map['month'] == 0){
$map['month'] = 12;
$map['year'] -= 1;
}
} }
$year = $map['year']; [$year, $month] = Util::parseYearMonth($yearMonth);
$month = $map['month']; $map['startYear'] = $startYear;
$map['year'] = $year;
$map['month'] = $month;
$globalHistory = getGlobalHistoryLogWithDate($year, $month); $globalHistory = getGlobalHistoryLogWithDate($year, $month);
$globalAction = getGlobalActionLogWithDate($year, $month); $globalAction = getGlobalActionLogWithDate($year, $month);
@@ -418,15 +422,27 @@ function LogHistory($isFirst=0) {
return -($lhs['power']<=>$rhs['power']); return -($lhs['power']<=>$rhs['power']);
}); });
$db->insert('ng_history', [ return [
'server_id' => UniqueConst::$serverID, 'server_id' => UniqueConst::$serverID,
'year' => $year, 'year' => $year,
'month' => $month, 'month' => $month,
'map' => Json::encode($map), 'map' => $map,
'global_history' => Json::encode($globalHistory), 'global_history' => $globalHistory,
'global_action' => Json::encode($globalAction), 'global_action' => $globalAction,
'nations' => Json::encode($nations), 'nations' => $nations,
]); ];
}
function LogHistory($isFirst=false) {
$history = getCurrentHistory($isFirst);
$db = DB::db();
$history['map'] = Json::encode($history['map']);
$history['global_history'] = Json::encode($history['global_history']);
$history['global_action'] = Json::encode($history['global_action']);
$history['nations'] = Json::encode($history['nations']);
$db->insert('ng_history', $history);
return true; return true;
} }
+6
View File
@@ -12,6 +12,7 @@ function printLimitMsg($turntime)
<head> <head>
<title>접속제한</title> <title>접속제한</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -118,6 +119,11 @@ function backButton()
return "<button type='button' class='btn btn-primary back_btn' onclick=location.replace('./')>돌아가기</button><br>"; return "<button type='button' class='btn btn-primary back_btn' onclick=location.replace('./')>돌아가기</button><br>";
} }
function gatewayButton()
{
return "<button type='button' class='btn btn-primary back_btn' onclick=location.replace('../')>돌아가기</button><br>";
}
function CoreBackButton() function CoreBackButton()
{ {
return "<button type='button' class='btn btn-primary back_btn' onclick=location.replace('v_chiefCenter.php')>돌아가기</button><br>"; return "<button type='button' class='btn btn-primary back_btn' onclick=location.replace('v_chiefCenter.php')>돌아가기</button><br>";
+14 -13
View File
@@ -8,11 +8,11 @@ class MapRequest{
public $neutralView; public $neutralView;
public $showMe; public $showMe;
function __construct($obj){ function __construct($obj){
$this->serverID = Util::array_get($obj['serverID'], null); $this->serverID = $obj['serverID'] ?? null;
$this->year = Util::array_get($obj['year']); $this->year = $obj['year'] ?? null;
$this->month = Util::array_get($obj['month']); $this->month = $obj['month'] ?? null;
$this->aux = Util::array_get($obj['aux'],[]); $this->aux = $obj['aux'] ?? [];
$this->neutralView = Util::array_get($obj['neutralView'], false); $this->neutralView = $obj['neutralView'] ?? false;
$this->showMe = $obj['showMe']; $this->showMe = $obj['showMe'];
} }
} }
@@ -35,7 +35,7 @@ function getHistoryMap($year, $month, ?string $serverID=null){
$map = DB::db()->queryFirstField('SELECT map FROM ng_history WHERE server_id = %s AND year=%i and month=%i', $map = DB::db()->queryFirstField('SELECT map FROM ng_history WHERE server_id = %s AND year=%i and month=%i',
$serverID, $serverID,
$year, $year,
$month); $month);
if(!$map){ if(!$map){
@@ -53,7 +53,7 @@ function getWorldMap($req){
if(is_array($req)){ if(is_array($req)){
$req = new MapRequest($req); $req = new MapRequest($req);
} }
if($req->year && $req->month){ if($req->year && $req->month){
return getHistoryMap($req->year, $req->month, $req->serverID??null); return getHistoryMap($req->year, $req->month, $req->serverID??null);
} }
@@ -98,7 +98,7 @@ function getWorldMap($req){
$spyInfo = (object)null; $spyInfo = (object)null;
if($myNation){ if($myNation){
$rawSpy = $db->queryFirstField('select `spy` from `nation` where `nation`=%i', $rawSpy = $db->queryFirstField('select `spy` from `nation` where `nation`=%i',
$myNation); $myNation);
if(strpos($rawSpy, '|') !== false || is_numeric($rawSpy)){ if(strpos($rawSpy, '|') !== false || is_numeric($rawSpy)){
@@ -123,16 +123,16 @@ function getWorldMap($req){
$nationList = []; $nationList = [];
foreach($db->query('select `nation`, `name`, `color`, `capital` from `nation`') as $row){ foreach($db->query('select `nation`, `name`, `color`, `capital` from `nation`') as $row){
$nationList[] = [ $nationList[] = [
Util::toInt($row['nation']), Util::toInt($row['nation']),
$row['name'], $row['name'],
$row['color'], $row['color'],
Util::toInt($row['capital']) Util::toInt($row['capital'])
]; ];
} }
if($myNation){ if($myNation){
//굳이 타국 도시에 있는 아국 장수 리스트를 뽑을 이유가 없음. 일단 다 뽑자. //굳이 타국 도시에 있는 아국 장수 리스트를 뽑을 이유가 없음. 일단 다 뽑자.
$shownByGeneralList = $shownByGeneralList =
array_map('\\sammo\\Util::toInt', array_map('\\sammo\\Util::toInt',
$db->queryFirstColumn('select distinct `city` from `general` where `nation` = %i', $db->queryFirstColumn('select distinct `city` from `general` where `nation` = %i',
$myNation)); $myNation));
@@ -143,7 +143,7 @@ function getWorldMap($req){
$cityList = []; $cityList = [];
foreach($db->query('select `city`, `level`, `state`, `nation`, `region`, `supply` from `city`') as $r){ foreach($db->query('select `city`, `level`, `state`, `nation`, `region`, `supply` from `city`') as $r){
$cityList[] = $cityList[] =
array_map('\\sammo\\Util::toInt', [$r['city'], $r['level'], $r['state'], $r['nation'], $r['region'], $r['supply']]); array_map('\\sammo\\Util::toInt', [$r['city'], $r['level'], $r['state'], $r['nation'], $r['region'], $r['supply']]);
} }
@@ -164,6 +164,7 @@ function getWorldMap($req){
'shownByGeneralList' => $shownByGeneralList, 'shownByGeneralList' => $shownByGeneralList,
'myCity' => $myCity, 'myCity' => $myCity,
'myNation' => $myNation, 'myNation' => $myNation,
'version' => 0,
'result' => true 'result' => true
]; ];
} }
+6 -7
View File
@@ -3,10 +3,10 @@ namespace sammo;
/** /**
* 내정 커맨드 사용시 성공 확률 계산 * 내정 커맨드 사용시 성공 확률 계산
* *
* @param General $general 장수 정보 * @param General $general 장수 정보
* @param string $type 내정 커맨드 타입, 'leadership' = 통솔 기반, 'strength' = 무력 기반, 'intel' = 지력 기반 * @param string $type 내정 커맨드 타입, 'leadership' = 통솔 기반, 'strength' = 무력 기반, 'intel' = 지력 기반
* *
* @return array 계산된 실패, 성공 확률 ('success' => 성공 확률, 'fail' => 실패 확률) * @return array 계산된 실패, 성공 확률 ('success' => 성공 확률, 'fail' => 실패 확률)
*/ */
function CriticalRatioDomestic(General $general, string $type) { function CriticalRatioDomestic(General $general, string $type) {
@@ -24,7 +24,7 @@ function CriticalRatioDomestic(General $general, string $type) {
506040(33%/30%), 505050(43%/40%), 504060(50%/50%) 506040(33%/30%), 505050(43%/40%), 504060(50%/50%)
* 통솔 내정 기준 * 통솔 내정 기준
756510(25%/22%), 707010(31%/28%), 657510(38%,35%), 756510(25%/22%), 707010(31%/28%), 657510(38%,35%),
505050(50%,50%), 107070(50%,50%) 505050(50%,50%), 107070(50%,50%)
*/ */
switch($type) { switch($type) {
@@ -60,13 +60,12 @@ function calcLeadershipBonus($officerLevel, $nationLevel):int{
return $lbonus; return $lbonus;
} }
function CriticalScoreEx(string $type):float { function CriticalScoreEx(RandUtil $rng, string $type):float {
if ($type == 'success') { if ($type == 'success') {
return Util::randRange(2.2, 3.0); return $rng->nextRange(2.2, 3.0);
} }
if ($type == 'fail') { if ($type == 'fail') {
return Util::randRange(0.2, 0.4); return $rng->nextRange(0.2, 0.4);
} }
return 1; return 1;
} }
+13 -61
View File
@@ -25,6 +25,7 @@ function requireAdminPermissionHTML()
<head> <head>
<title>관리메뉴</title> <title>관리메뉴</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=1024" /> <meta name="viewport" content="width=1024" />
<?= WebUtil::printCSS('../d_shared/common.css') ?> <?= WebUtil::printCSS('../d_shared/common.css') ?>
@@ -60,6 +61,11 @@ function chiefTurnTable()
"; ";
} }
function templateLimitMsg(string $turntime): string
{
return "이미 너무 많은 접속을 하셨습니다. 다음 턴에 다시 시도해주세요. (턴시간: {$turntime})";
}
function displayiActionObjInfo(?iAction $action) function displayiActionObjInfo(?iAction $action)
{ {
if ($action === null) { if ($action === null) {
@@ -125,7 +131,7 @@ function allButton(bool $seizeNPCMode, array $opts = [])
$site = "a_npcList.php"; $site = "a_npcList.php";
$call = "빙의일람"; $call = "빙의일람";
} else { } else {
$site = "a_vote.php"; $site = "v_vote.php";
$call = "설문조사"; $call = "설문조사";
} }
@@ -142,47 +148,6 @@ function allButton(bool $seizeNPCMode, array $opts = [])
], $opts)); ], $opts));
} }
function commandButton(array $opts = [])
{
$session = Session::getInstance();
$userID = Session::getUserID();
if (!$session->isGameLoggedIn()) {
return '';
}
$db = DB::db();
$me = $db->queryFirstRow("select no,nation,officer_level,belong,permission,penalty from general where owner=%i", $userID);
$nation = $db->queryFirstRow("select nation,level,color,secretlimit from nation where nation=%i", $me['nation']) ?? [
'nation' => 0,
'level' => 0,
'secretlimit' => 99,
'color' => '#000000'
];
$bgColor = Util::array_get($nation['color']) ?: '#000000';
$fgColor = newColor($bgColor);
$templates = new \League\Plates\Engine(__DIR__ . '/templates');
$showSecret = false;
$permission = checkSecretPermission($me);
if ($permission >= 1) {
$showSecret = true;
} else if ($me['officer_level'] == 0) {
$showSecret = false;
}
return $templates->render('commandButton', array_merge([
'bgColor' => $bgColor,
'fgColor' => $fgColor,
'meLevel' => $me['officer_level'],
'nationLevel' => $nation['level'],
'showSecret' => $showSecret,
'permission' => $permission,
], $opts));
}
function formatWounded(int $value, int $wound): string function formatWounded(int $value, int $wound): string
{ {
if ($wound == 0) { if ($wound == 0) {
@@ -215,36 +180,23 @@ function formatLeadershipBonus(int $value): string
return "<font color=cyan>+{$value}</font>"; return "<font color=cyan>+{$value}</font>";
} }
function formatName(string $name, int $npc): string
{
if ($npc == 1) {
$name = "<font color='skyblue'>$name</font>";
} else if ($npc > 1) {
$name = "<font color='cyan'>$name</font>";
}
return $name;
}
function getMapTheme(): string function getMapTheme(): string
{ {
$db = DB::db(); return GameConst::$mapName;
$gameStor = KVStorage::getStorage($db, 'game_env');
$mapTheme = $gameStor->map_theme ?? 'che';
return $mapTheme;
} }
function getMapHtml(?string $mapTheme = null) function getMapHtml(?string $mapName = null)
{ {
$templates = new \League\Plates\Engine(__DIR__ . '/templates'); $templates = new \League\Plates\Engine(__DIR__ . '/templates');
if ($mapTheme === null) { if ($mapName === null) {
$db = DB::db(); $mapName = GameConst::$mapName;
$gameStor = KVStorage::getStorage($db, 'game_env');
$mapTheme = $gameStor->map_theme ?? 'che';
} }
return $templates->render('map', [ return $templates->render('map', [
'mapTheme' => $mapTheme 'mapName' => $mapName
]); ]);
} }
+50 -255
View File
@@ -1,129 +1,42 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\InheritanceKey;
use sammo\Enums\RankColumn;
use Ds\Map;
use sammo\Enums\ResourceType;
use sammo\Event\Action;
/** /**
* 시간 단위로 일어나는 이벤트들에 대한 함수 모음 * 시간 단위로 일어나는 이벤트들에 대한 함수 모음
*/ */
/** @deprecated */
//1월마다 실행 function processSumInheritPointRank(){
function processSpring() {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
//인구 증가 $e_env = $gameStor->getValues(['startyear', 'year', 'month']);
popIncrease(); $e_env['currentEventID'] = 0;
// 1월엔 무조건 내정 1% 감소 Action::build(["ProcessIncome", ResourceType::rice->value])->run($e_env);
$db->update('city',[
'dead'=>0,
'agri'=>$db->sqleval('agri * 0.99'),
'comm'=>$db->sqleval('comm * 0.99'),
'secu'=>$db->sqleval('secu * 0.99'),
'def'=>$db->sqleval('def * 0.99'),
'wall'=>$db->sqleval('wall * 0.99'),
],true);
// > 10000 유지비 3%, > 1000 유지비 1%
// 유지비 1%
$db->update('general', [
'gold'=>$db->sqleval('IF(gold > 10000, gold * 0.97, gold * 0.99)')
], 'gold > 1000');
// > 100000 유지비 5%, > 100000 유지비 3%, > 1000 유지비 1%
$db->update('nation', [
'gold'=>$db->sqleval('IF(gold > 100000, gold * 0.95, IF(gold > 10000, gold * 0.97, gold * 0.99))')
], 'gold > 1000');
$admin = $gameStor->getValues(['year', 'month']);
pushGlobalHistoryLog(["<R>★</>{$admin['year']}{$admin['month']}월: <S>모두들 즐거운 게임 하고 계신가요? ^^ <Y>매너 있는 플레이</> 부탁드리고, <M>지나친 훼접</>은 삼가주세요~</>"], $admin['year'], $admin['month']);
} }
/** @deprecated */
function processGoldIncome() { function processGoldIncome() {
$db = DB::db(); $db = DB::db();
$gameStor = new KVStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); $e_env = $gameStor->getValues(['startyear', 'year', 'month']);
$adminLog = []; $e_env['currentEventID'] = 0;
Action::build(["ProcessIncome", ResourceType::gold->value])->run($e_env);
$nationList = $db->query('SELECT name,nation,capital,gold,level,rate_tmp,bill,type from nation');
$cityListByNation = Util::arrayGroupBy($db->query('SELECT * FROM city'), 'nation');
$generalRawListByNation = Util::arrayGroupBy($db->query('SELECT no,name,nation,gold,officer_level,dedication,city FROM general WHERE npc != 5'), 'nation');
//국가별 처리
foreach($nationList as $nation) {
$nationID = $nation['nation'];
$generalRawList = $generalRawListByNation[$nationID];
$income = getGoldIncome($nationID, $nation['level'], $nation['rate_tmp'], $nation['capital'], $nation['type'], $cityListByNation[$nationID]??[]);
$originoutcome = getOutcome(100, $generalRawList);
$outcome= Util::round($nation['bill'] / 100 * $originoutcome);
// 실제 지급량 계산
$nation['gold'] += $income;
// 기본량도 안될경우
if($nation['gold'] < GameConst::$basegold) {
$realoutcome = 0;
// 실지급률
$ratio = 0;
//기본량은 넘지만 요구량이 안될경우
} elseif($nation['gold'] - GameConst::$basegold < $outcome) {
$realoutcome = $nation['gold'] - GameConst::$basegold;
$nation['gold'] = GameConst::$basegold;
// 실지급률
$ratio = $realoutcome / $originoutcome;
} else {
$realoutcome = $outcome;
$nation['gold'] -= $realoutcome;
// 실지급률
$ratio = $realoutcome / $originoutcome;
}
$nation['gold'] = Util::valueFit($nation['gold'], GameConst::$basegold);
$adminLog[] = StringUtil::padStringAlignRight((string)$nation['name'],12," ")
." // 세금 : ".StringUtil::padStringAlignRight((string)$income,6," ")
." // 세출 : ".StringUtil::padStringAlignRight((string)$originoutcome,6," ")
." // 실제 : ".tab2((string)$realoutcome,6," ")
." // 지급률 : ".tab2((string)round($ratio*100,2),5," ")
." % // 결과금 : ".tab2((string)$nation['gold'],6," ");
$incomeText = number_format($income);
$incomeLog = "이번 수입은 금 <C>$incomeText</>입니다.";
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
$nationStor->prev_income_gold = $income;
$db->update('nation', [
'gold'=>$nation['gold']
], 'nation=%i', $nationID);
// 각 장수들에게 지급
foreach ($generalRawList as $rawGeneral) {
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
$gold = Util::round(getBill($generalObj->getVar('dedication'))*$ratio);
$generalObj->increaseVar('gold', $gold);
$logger = $generalObj->getLogger();
if($generalObj->getVar('officer_level') > 4){
$logger->pushGeneralActionLog($incomeLog, $logger::PLAIN);
}
$goldText = number_format($gold);
$logger->pushGeneralActionLog("봉급으로 금 <C>$goldText</>을 받았습니다.", $logger::PLAIN);
$generalObj->applyDB($db);
}
}
$logger = new ActionLogger(0, 0, $year, $month);
$logger->pushGlobalHistoryLog('<W><b>【지급】</b></>봄이 되어 봉록에 따라 자금이 지급됩니다.');
$logger->flush();
pushAdminLog($adminLog);
} }
function popIncrease() { function popIncrease() {
$db = DB::db(); $db = DB::db();
$nationList = $db->queryAllLists('SELECT nation,rate_tmp,type FROM nation'); $nationList = $db->queryAllLists('SELECT nation,rate_tmp,type FROM nation');
// 인구 및 민심 // 인구 및 민심
$db->update('city', [ $db->update('city', [
@@ -138,7 +51,7 @@ function popIncrease() {
foreach($nationList as [$nationID, $taxRate, $nationType]){ foreach($nationList as [$nationID, $taxRate, $nationType]){
$nationTypeObj = buildNationTypeClass($nationType); $nationTypeObj = buildNationTypeClass($nationType);
$popRatio = (30 - $taxRate)/200; // 20일때 5% 5일때 12.5% 50일때 -10% $popRatio = (30 - $taxRate)/200; // 20일때 5% 5일때 12.5% 50일때 -10%
$popRatio = $nationTypeObj->onCalcNationalIncome('pop', $popRatio); $popRatio = $nationTypeObj->onCalcNationalIncome('pop', $popRatio);
@@ -246,33 +159,10 @@ function getGoldIncome(int $nationID, int $nationLevel, float $taxRate, int $cap
} }
$cityIncome *= ($taxRate / 20); $cityIncome *= ($taxRate / 20);
return $cityIncome; return $cityIncome;
} }
function processWarIncome() {
$db = DB::db();
$cityListByNation = Util::arrayGroupBy($db->query('SELECT * FROM city'), 'nation');
foreach(getAllNationStaticInfo() as $nation){
if($nation['level'] <= 0){
continue;
}
$nationID = $nation['nation'];
$income = getWarGoldIncome($nation['type'], $cityListByNation[$nationID]??[]);
$db->update('nation', [
'gold'=>$db->sqleval('gold + %i', $income)
], 'nation=%i', $nationID);
}
// 10%수입, 20%부상병
$db->update('city', [
'pop'=>$db->sqleval('pop + dead * %d', 0.2),
'dead'=>0
], true);
}
function getWarGoldIncome(string $nationType, array $cityList){ function getWarGoldIncome(string $nationType, array $cityList){
$nationTypeObj = buildNationTypeClass($nationType); $nationTypeObj = buildNationTypeClass($nationType);
@@ -284,116 +174,14 @@ function getWarGoldIncome(string $nationType, array $cityList){
return $cityIncome; return $cityIncome;
} }
/** @deprecated */
//7월마다 실행
function processFall() {
$db = DB::db();
//인구 증가
popIncrease();
// 7월엔 무조건 내정 1% 감소
$db->update('city',[
'dead'=>0,
'agri'=>$db->sqleval('agri * 0.99'),
'comm'=>$db->sqleval('comm * 0.99'),
'secu'=>$db->sqleval('secu * 0.99'),
'def'=>$db->sqleval('def * 0.99'),
'wall'=>$db->sqleval('wall * 0.99'),
],true);
// > 10000 유지비 3%, > 1000 유지비 1%
// 유지비 1%
$db->update('general', [
'rice'=>$db->sqleval('IF(rice > 10000, rice * 0.97, rice * 0.99)')
], 'rice > 1000');
// > 100000 유지비 5%, > 100000 유지비 3%, > 1000 유지비 1%
$db->update('nation', [
'rice'=>$db->sqleval('IF(rice > 100000, rice * 0.95, IF(rice > 10000, rice * 0.97, rice * 0.99))')
], 'rice > 1000');
}
function processRiceIncome() { function processRiceIncome() {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month] = $gameStor->getValuesAsArray(['year', 'month']); $e_env = $gameStor->getValues(['startyear', 'year', 'month']);
$adminLog = []; $e_env['currentEventID'] = 0;
Action::build(["ProcessIncome", ResourceType::rice->value])->run($e_env);
$nationList = $db->query('SELECT name,level,nation,capital,rice,rate_tmp,bill,type from nation');
$cityListByNation = Util::arrayGroupBy($db->query('SELECT * FROM city'), 'nation');
$generalRawListByNation = Util::arrayGroupBy($db->query('SELECT no,name,nation,rice,officer_level,dedication,city FROM general WHERE npc != 5'), 'nation');
//국가별 처리
foreach($nationList as $nation) {
$nationID = $nation['nation'];
$generalRawList = $generalRawListByNation[$nationID];
$income = getRiceIncome($nation['nation'], $nation['level'], $nation['rate_tmp'], $nation['capital'], $nation['type'], $cityListByNation[$nationID]??[]);
$income += getWallIncome($nation['nation'], $nation['level'], $nation['rate_tmp'], $nation['capital'], $nation['type'], $cityListByNation[$nationID]??[]);
$originoutcome = getOutcome(100, $generalRawList);
$outcome= Util::round($nation['bill'] / 100 * $originoutcome);
// 실제 지급량 계산
$nation['rice'] += $income;
// 기본량도 안될경우
if($nation['rice'] < GameConst::$baserice) {
$realoutcome = 0;
// 실지급률
$ratio = 0;
//기본량은 넘지만 요구량이 안될경우
} elseif($nation['rice'] - GameConst::$baserice < $outcome) {
$realoutcome = $nation['rice'] - GameConst::$baserice;
$nation['rice'] = GameConst::$baserice;
// 실지급률
$ratio = $realoutcome / $originoutcome;
} else {
$realoutcome = $outcome;
$nation['rice'] -= $realoutcome;
// 실지급률
$ratio = $realoutcome / $originoutcome;
}
$nation['rice'] = Util::valueFit($nation['rice'], GameConst::$baserice);
$adminLog[] = StringUtil::padStringAlignRight($nation['name'],12," ")
." // 세곡 : ".StringUtil::padStringAlignRight((string)$income,6," ")
." // 세출 : ".StringUtil::padStringAlignRight((string)$originoutcome,6," ")
." // 실제 : ".tab2((string)$realoutcome,6," ")
." // 지급률 : ".tab2((string)round($ratio*100,2),5," ")
." % // 결과곡 : ".tab2((string)$nation['rice'],6," ");
$incomeText = number_format($income);
$incomeLog = "이번 수입은 쌀 <C>$incomeText</>입니다.";
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
$nationStor->prev_income_rice = $income;
$db->update('nation', [
'rice'=>$nation['rice']
], 'nation=%i', $nationID);
// 각 장수들에게 지급
foreach ($generalRawList as $rawGeneral) {
$generalObj = new General($rawGeneral, null, null, null, $year, $month, false);
$rice = Util::round(getBill($generalObj->getVar('dedication'))*$ratio);
$generalObj->increaseVar('rice', $rice);
$logger = $generalObj->getLogger();
if($generalObj->getVar('officer_level') > 4){
$logger->pushGeneralActionLog($incomeLog, $logger::PLAIN);
}
$riceText = number_format($rice);
$logger->pushGeneralActionLog("봉급으로 쌀 <C>$riceText</>을 받았습니다.", $logger::PLAIN);
$generalObj->applyDB($db);
}
}
$logger = new ActionLogger(0, 0, $year, $month);
$logger->pushGlobalHistoryLog('<W><b>【지급】</b></>가을이 되어 봉록에 따라 군량이 지급됩니다.');
$logger->flush();
pushAdminLog($adminLog);
} }
function getRiceIncome(int $nationID, int $nationLevel, float $taxRate, int $capitalID, string $nationType, ?array $cityList) { function getRiceIncome(int $nationID, int $nationLevel, float $taxRate, int $capitalID, string $nationType, ?array $cityList) {
@@ -418,7 +206,7 @@ function getRiceIncome(int $nationID, int $nationLevel, float $taxRate, int $cap
} }
$cityIncome *= ($taxRate / 20); $cityIncome *= ($taxRate / 20);
return $cityIncome; return $cityIncome;
} }
@@ -439,12 +227,12 @@ function getWallIncome(int $nationID, int $nationLevel, float $taxRate, int $cap
$cityIncome = 0; $cityIncome = 0;
foreach($cityList as $rawCity){ foreach($cityList as $rawCity){
$cityID = $rawCity['city']; $cityID = $rawCity['city'];
$cityIncome += calcCityWallRiceIncome($rawCity, $officersCnt[$cityID]??0, $capitalID == $cityID, $nationLevel, $nationTypeObj); $cityIncome += calcCityWallRiceIncome($rawCity, $officersCnt[$cityID]??0, $capitalID == $cityID, $nationLevel, $nationTypeObj);
} }
$cityIncome *= ($taxRate / 20); $cityIncome *= ($taxRate / 20);
return $cityIncome; return $cityIncome;
} }
@@ -460,7 +248,7 @@ function getOutcome(float $billRate, array $generalList) {
return $outcome; return $outcome;
} }
function tradeRate() { function tradeRate(RandUtil $rng) {
$db = DB::db(); $db = DB::db();
foreach($db->query('SELECT city,level FROM city') as $city){ foreach($db->query('SELECT city,level FROM city') as $city){
@@ -475,8 +263,8 @@ function tradeRate() {
7=>0.8, 7=>0.8,
8=>1 8=>1
][$city['level']]; ][$city['level']];
if($prob > 0 && Util::randBool($prob)) { if($prob > 0 && $rng->nextBool($prob)) {
$trade = Util::randRangeInt(95, 105); $trade = $rng->nextRangeInt(95, 105);
} else { } else {
$trade = null; $trade = null;
} }
@@ -486,7 +274,7 @@ function tradeRate() {
} }
} }
function disaster() { function disaster(RandUtil $rng) {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
@@ -507,7 +295,7 @@ function disaster() {
10=>0 10=>0
]; ];
$isGood = Util::randBool($boomingRate[$month]); $isGood = $rng->nextBool($boomingRate[$month]);
$targetCityList = []; $targetCityList = [];
@@ -520,9 +308,9 @@ function disaster() {
} }
else { else {
$raiseProp = 0.06 - ($city['secu'] / $city['secu_max']) * 0.05; // 1 ~ 6% $raiseProp = 0.06 - ($city['secu'] / $city['secu_max']) * 0.05; // 1 ~ 6%
} }
if(Util::randBool($raiseProp)) { if($rng->nextBool($raiseProp)) {
$targetCityList[] = $city; $targetCityList[] = $city;
} }
} }
@@ -568,7 +356,7 @@ function disaster() {
10 => null 10 => null
]; ];
[$logTitle, $stateCode, $logBody] = Util::choiceRandom(($isGood?$boomingTextList:$disasterTextList)[$month]); [$logTitle, $stateCode, $logBody] = $rng->choice(($isGood?$boomingTextList:$disasterTextList)[$month]);
$logger = new ActionLogger(0, 0, $year, $month, false); $logger = new ActionLogger(0, 0, $year, $month, false);
@@ -576,7 +364,14 @@ function disaster() {
$logger->flush(); $logger->flush();
if (!$isGood) { if (!$isGood) {
$generalListByCity = Util::arrayGroupBy($db->query('SELECT no, nation, city, injury, crew, atmos, train FROM general WHERE city IN %li', Util::squeezeFromArray($targetCityList, 'city')), 'city'); [$queryColumns,,] = General::mergeQueryColumn();
$generalListByCity = Util::arrayGroupBy(
$db->query(
'SELECT %l FROM general WHERE city IN %li',
Util::formatListOfBackticks($queryColumns),
Util::squeezeFromArray($targetCityList, 'city')
),
'city');
//NOTE: 쿼리 1번이지만 복잡하기 vs 쿼리 여러번이지만 조금 더 깔끔하기 //NOTE: 쿼리 1번이지만 복잡하기 vs 쿼리 여러번이지만 조금 더 깔끔하기
foreach ($targetCityList as $city) { foreach ($targetCityList as $city) {
$affectRatio = Util::valueFit($city['secu'] / $city['secu_max'] / 0.8, 0, 1); $affectRatio = Util::valueFit($city['secu'] / $city['secu_max'] / 0.8, 0, 1);
@@ -592,15 +387,15 @@ function disaster() {
'def'=>$db->sqleval('def * %d', $affectRatio), 'def'=>$db->sqleval('def * %d', $affectRatio),
'wall'=>$db->sqleval('wall * %d', $affectRatio), 'wall'=>$db->sqleval('wall * %d', $affectRatio),
], 'city = %i', $city['city']); ], 'city = %i', $city['city']);
$generalList = array_map( $generalList = array_map(
function($rawGeneral) use ($city, $year, $month){ function($rawGeneral) use ($city, $year, $month){
return new General($rawGeneral, null, $city, null, $year, $month, false); return new General($rawGeneral, null, null, $city, null, $year, $month, false);
}, },
$generalListByCity[$city['city']]??[] $generalListByCity[$city['city']]??[]
); );
SabotageInjury($generalList, '재난'); SabotageInjury($rng, $generalList, '재난');
} }
} }
else{ else{
@@ -619,7 +414,7 @@ function disaster() {
'wall'=>$db->sqleval('least(wall * %d, wall_max)', $affectRatio), 'wall'=>$db->sqleval('least(wall * %d, wall_max)', $affectRatio),
], 'city = %i', $city['city']); ], 'city = %i', $city['city']);
} }
} }
+215 -649
View File
@@ -2,18 +2,28 @@
namespace sammo; namespace sammo;
use sammo\DTO\BettingInfo;
use sammo\Enums\InheritanceKey;
/**
* @param int $turnTerm 서버 턴 단위
* @return int 토너먼트 초 단위
*/
function calcTournamentTerm(int $turnTerm): int{
return Util::valueFit($turnTerm, 5, 120);
}
function processTournament() function processTournament()
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time']); $admin = $gameStor->getValues(['tournament', 'phase', 'tnmt_type', 'tnmt_auto', 'tnmt_time', 'turnterm', 'last_tournament_betting_id']);
$now = new \DateTime(); $now = new \DateTime();
$offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp(); $offset = $now->getTimestamp() - (new \DateTime($admin['tnmt_time']))->getTimestamp();
//수동일땐 무시 //수동일땐 무시
if ($admin['tnmt_auto'] == 0) { if (!$admin['tnmt_auto']) {
return; return;
} }
@@ -26,31 +36,7 @@ function processTournament()
} }
//현시간이 스탬프 지나친경우 //현시간이 스탬프 지나친경우
switch ($admin['tnmt_auto']) { $unit = calcTournamentTerm($admin['turnterm']);
case 1:
$unit = 720;
break;
case 2:
$unit = 420;
break;
case 3:
$unit = 180;
break;
case 4:
$unit = 60;
break;
case 5:
$unit = 30;
break;
case 6:
$unit = 15;
break;
case 7:
$unit = 5;
break;
default:
throw new MustNotBeReachedException();
}
//업데이트 횟수 //업데이트 횟수
$iter = intdiv($offset, $unit) + 1; $iter = intdiv($offset, $unit) + 1;
@@ -90,9 +76,12 @@ function processTournament()
final16set(); final16set();
$tnmt = 6; $tnmt = 6;
$phase = 0; $phase = 0;
startBetting(); startBetting($type, $unit);
break; break;
case 6: //베팅중 case 6: //베팅중
$bettingID = $admin['last_tournament_betting_id'];
$betting = new Betting($bettingID);
$betting->closeBetting();
$tnmt = 7; $tnmt = 7;
$phase = 0; $phase = 0;
break; break;
@@ -131,10 +120,7 @@ function processTournament()
//베팅은 무조건 60페이즈후 진행(최대 1시간) //베팅은 무조건 60페이즈후 진행(최대 1시간)
if ($tnmt == 6) { if ($tnmt == 6) {
$betTerm = $unit * 60; $betTerm = Util::valueFit($unit * 60, null, 3600);
if ($betTerm > 3600) {
$betTerm = 3600;
}
//처리 초 더한 날짜 //처리 초 더한 날짜
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i + $betTerm); $dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i + $betTerm);
$gameStor->tournament = $tnmt; $gameStor->tournament = $tnmt;
@@ -142,20 +128,6 @@ function processTournament()
$gameStor->tnmt_time = $dt; $gameStor->tnmt_time = $dt;
return; return;
} }
if ($admin['tnmt_auto'] == 1) {
//처리 초 더한 날짜
$dt = date("Y-m-d H:i:s", strtotime($admin['tnmt_time']) + $unit * $i);
$hr = substr($dt, 11, 2);
//지정시간대 넘어가면 중단 20~24시
if ($hr < 20) {
$dt = substr($dt, 0, 11) . "20:00:00";
$gameStor->tournament = $tnmt;
$gameStor->phase = $phase;
$gameStor->tnmt_time = $dt;
return;
}
}
} }
$second = $unit * $iter; $second = $unit * $iter;
@@ -164,40 +136,22 @@ function processTournament()
$gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s'); $gameStor->tnmt_time = (new \DateTimeImmutable($admin['tnmt_time']))->add(new \DateInterval("PT{$second}S"))->format('Y-m-d H:i:s');
} }
function getTournamentTerm() function getTournamentTermText(int $turnTerm)
{ {
$db = DB::db(); $term = calcTournamentTerm($turnTerm);
$gameStor = KVStorage::getStorage($db, 'game_env');
$tnmt_auto = $gameStor->tnmt_auto; if ($term % 60 === 0) {
$termMin = intdiv($term, 60);
switch ($tnmt_auto) { return "경기당 {$termMin}";
case 0:
$str = '';
break;
case 1:
$str = "경기당 12분";
break;
case 2:
$str = "경기당 7분";
break;
case 3:
$str = "경기당 3분";
break;
case 4:
$str = "경기당 1분";
break;
case 5:
$str = "경기당 30초";
break;
case 6:
$str = "경기당 15초";
break;
case 7:
$str = "경기당 5초";
break;
} }
return $str;
if ($term > 60) {
$termSec = $term % 60;
$termMin = intdiv($term, 60);
return "경기당 {$termMin}{$termSec}";
}
return "경기당 {$term}";
} }
function getTournamentTime() function getTournamentTime()
@@ -256,15 +210,13 @@ function getTournament(int $tnmt)
][$tnmt] ?? "TOURNAMENT_TYPE_ERR_{$tnmt}"; ][$tnmt] ?? "TOURNAMENT_TYPE_ERR_{$tnmt}";
} }
function printRow($k, $npc, $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl, $prmt) function printRow(int $k, int $npc, string $name, $abil, $tgame, $win, $draw, $lose, $gd, $gl, $prmt)
{ {
$k += 1; $k += 1;
if ($prmt > 0) { if ($prmt > 0) {
$name = "<font color=orange>" . $name . "</font>"; $name = "<font color=orange>" . $name . "</font>";
} elseif ($npc >= 2) { } else if ($npc > 0) {
$name = "<font color=cyan>" . $name . "</font>"; $name = formatName($name, $npc);
} elseif ($npc == 1) {
$name = "<font color=skyblue>" . $name . "</font>";
} }
echo "<tr align=center><td class='bg2'>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>"; echo "<tr align=center><td class='bg2'>$k</td><td style='font-size:80%;'>$name</td><td>$abil</td><td>$tgame</td><td>$win</td><td>$draw</td><td>$lose</td><td>$gd</td><td>$gl</td></tr>";
} }
@@ -322,69 +274,27 @@ function printFighting($tournament, $phase)
} }
} }
function startTournament($auto, $type) function startTournament($type)
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
eraseTnmtFightLogAll(); eraseTnmtFightLogAll();
switch ($auto) { $admin = $gameStor->getValues(['year', 'month', 'turnterm']);
case 1: $turnTerm = $admin['turnterm'];
$unit = 60; $unit = calcTournamentTerm($turnTerm);
break;
case 2:
$unit = 60;
break;
case 3:
$unit = 60;
break;
case 4:
$unit = 60;
break;
case 5:
$unit = 30;
break;
case 6:
$unit = 15;
break;
case 7:
$unit = 5;
break;
default:
$unit = 60;
break;
}
$admin = $gameStor->getValues(['year', 'month']); $gameStor->tnmt_auto = true;
$gameStor->tnmt_auto = $auto;
$gameStor->tnmt_time = (new \DateTimeImmutable())->add(new \DateInterval("PT{$unit}M"))->format('Y-m-d H:i:s'); $gameStor->tnmt_time = (new \DateTimeImmutable())->add(new \DateInterval("PT{$unit}M"))->format('Y-m-d H:i:s');
$gameStor->tournament = 1; $gameStor->tournament = 1;
$gameStor->tnmt_type = $type; $gameStor->tnmt_type = $type;
$gameStor->last_tournament_betting_id = 0;
$gameStor->phase = 0; $gameStor->phase = 0;
$db->update('general', [ $db->update('general', [
'tournament' => 0, 'tournament' => 0,
], true); ], true);
$db->update('betting', [
'bet0' => 0,
'bet1' => 0,
'bet2' => 0,
'bet3' => 0,
'bet4' => 0,
'bet5' => 0,
'bet6' => 0,
'bet7' => 0,
'bet8' => 0,
'bet9' => 0,
'bet10' => 0,
'bet11' => 0,
'bet12' => 0,
'bet13' => 0,
'bet14' => 0,
'bet15' => 0
], true);
$db->query('TRUNCATE TABLE tournament'); $db->query('TRUNCATE TABLE tournament');
$opener = $db->queryFirstField('SELECT `general`.`name` FROM `general` JOIN `nation` ON `general`.`nation` = `nation`.`nation` WHERE `general`.`officer_level` = 12 AND `nation`.`level` = 7 ORDER BY rand() LIMIT 1'); $opener = $db->queryFirstField('SELECT `general`.`name` FROM `general` JOIN `nation` ON `general`.`nation` = `nation`.`nation` WHERE `general`.`officer_level` = 12 AND `nation`.`level` = 7 ORDER BY rand() LIMIT 1');
@@ -411,44 +321,100 @@ function startTournament($auto, $type)
pushGlobalHistoryLog($history, $admin['year'], $admin['month']); pushGlobalHistoryLog($history, $admin['year'], $admin['month']);
} }
function startBetting() function getDummyBettingInfo(string $tnmt_type): BettingInfo
{
return new BettingInfo(
id: 0,
type: 'tournament',
name: $tnmt_type,
finished: true,
selectCnt: 1,
isExclusive: null,
reqInheritancePoint: false,
openYearMonth: 0,
closeYearMonth: 0,
candidates: [],
winner: null,
);
}
function startBetting($type)
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
[$year, $month, $startyear] = $gameStor->getValuesAsArray(['year', 'month', 'startyear']); [$year, $month, $startyear, $turnterm] = $gameStor->getValuesAsArray(['year', 'month', 'startyear', 'turnterm']);
pushGlobalHistoryLog([ pushGlobalHistoryLog([
"<S>◆</>{$year}{$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!" "<S>◆</>{$year}{$month}월:<B><b>【대회】</b></>우승자를 예상하는 <C>내기</>가 진행중입니다! 호사가의 참여를 기다립니다!"
], $year, $month); ], $year, $month);
[$typeText, $statName, $statKey] = [
['전력전', '종능', 'total'],
['통솔전', '통솔', 'leadership'],
['일기토', '무력', 'strength'],
['설전', '지력', 'intel'],
][$type];
$bettingID = Betting::genNextBettingID();
//어차피 강제로 닫을 것이므로 크게 신경쓰지 않는다.
$openYearMonth = Util::joinYearMonth($year, $month);
$closeYearMonth = $openYearMonth + 120;
/** @var \sammo\DTO\SelectItem[] */
$candidates = [];
$generalList = $db->query('SELECT no,npc,name,win,leadership,strength,intel,leadership+strength+intel as total from tournament where grp>=20 order by grp, grp_no LIMIT 16');
foreach ($generalList as $idx => $general) {
if ($general['no'] <= 0) {
continue;
}
$general['idx'] = $idx;
$candidates[$general['no']] = new \sammo\DTO\SelectItem(
title: $general['name'],
info: "{$statName}: {$general[$statKey]}",
isHtml: null,
aux: $general
);
}
Betting::openBetting(new BettingInfo(
id: $bettingID,
type: 'tournament',
name: $typeText,
finished: false,
selectCnt: 1,
isExclusive: null,
reqInheritancePoint: false,
openYearMonth: $openYearMonth,
closeYearMonth: $closeYearMonth,
candidates: $candidates,
winner: null,
));
$betting = new Betting($bettingID);
$gameStor->last_tournament_betting_id = $bettingID;
$betGold = Util::valueFit(floor((3 + $year - $startyear) * 0.334) * 10, 10); $betGold = Util::valueFit(floor((3 + $year - $startyear) * 0.334) * 10, 10);
$rng = new RandUtil(new LiteHashDRBG(Util::simpleSerialize(
UniqueConst::$hiddenSeed,
'OpenBettingTournament',
$bettingID,
)));
$npcList = $db->queryFirstColumn('SELECT no FROM general WHERE npc >= 2 AND gold >= (500 + %i)', $betGold); $npcList = $db->queryFirstColumn('SELECT no FROM general WHERE npc >= 2 AND gold >= (500 + %i)', $betGold);
$npcBet = []; $npcBet = [];
$betSum = [
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
];
$targetList = array_keys($candidates);
foreach ($npcList as $npcID) { foreach ($npcList as $npcID) {
$target = Util::randRangeInt(0, 15); $target = $rng->choice($targetList);
$betSum[$target] += $betGold;
$npcBet[] = [$npcID, $target]; $npcBet[] = [$npcID, $target];
} }
$db->update('general', [
'gold' => $db->sqleval('gold - %i', $betGold),
], 'no IN %li', $npcList);
foreach ($npcBet as [$npcID, $betTarget]) { foreach ($npcBet as [$npcID, $betTarget]) {
$targetKey = "bet{$betTarget}"; $betting->bet($npcID, null, [$betTarget], $betGold);
$db->update('betting', [
"bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betGold),
], 'general_id = %i', $npcID);
}
foreach ($betSum as $betTarget => $betSumGold) {
$targetKey = "bet{$betTarget}";
$db->update('betting', [
"bet{$betTarget}" => $db->sqleval('%b + %i', $targetKey, $betSumGold),
], 'general_id = 0');
} }
} }
@@ -507,24 +473,26 @@ function fillLowGenAll($tnmt_type)
}; };
//자동신청하고, 돈 있고, 아직 참가 안한 장수 //자동신청하고, 돈 있고, 아직 참가 안한 장수
/** @var array<array{0:array,1:float}> */
$freeJoinerCandidate = []; $freeJoinerCandidate = [];
foreach($db->query( foreach ($db->query(
'SELECT no,npc,name,leadership,strength,intel,explevel,horse,weapon,book from general where tnmt=1 and tournament=0', 'SELECT no,npc,name,leadership,strength,intel,explevel,horse,weapon,book from general where tnmt=1 and tournament=0',
) as $gen){ ) as $gen) {
$score = $scoringCandFunction($gen); $score = $scoringCandFunction($gen);
$freeJoinerCandidate[$gen['no']] = [$gen, $score**1.5]; $freeJoinerCandidate[$gen['no']] = [$gen, $score ** 1.5];
} }
$joinersValues = []; $joinersValues = [];
$joinersIdx = []; $joinersIdx = [];
foreach(Util::range($toBeFilledCnt) as $_){ foreach (Util::range($toBeFilledCnt) as $_) {
if(!$freeJoinerCandidate){ if (!$freeJoinerCandidate) {
break; break;
} }
$general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate); $general = Util::choiceRandomUsingWeightPair($freeJoinerCandidate);
/** @var array $general */
unset($freeJoinerCandidate[$general['no']]); unset($freeJoinerCandidate[$general['no']]);
$grpIdx = array_keys($grpCount, min($grpCount))[0]; $grpIdx = array_keys($grpCount, min($grpCount))[0];
@@ -576,160 +544,37 @@ function fillLowGenAll($tnmt_type)
//7 8강 //7 8강
//8 4강 //8 4강
//9 결승 //9 결승
function getTwo($tournament, $phase) /**
* @return array{0:int,1:int}
*/
function getTwo(int $tournament, int $phase): array
{ {
$cand = []; $cand = [];
switch ($tournament) { switch ($tournament) {
case 2: case 2:
//예선 //예선
switch ($phase % 28) { $candMap = [
case 0: [0, 1], [2, 3], [4, 5], [6, 7],
$cand[0] = 0; [0, 2], [1, 3], [4, 6], [5, 7],
$cand[1] = 1; [0, 3], [1, 6], [2, 5], [4, 7],
break; [0, 4], [1, 5], [2, 6], [3, 7],
case 1: [0, 5], [1, 4], [2, 7], [3, 6],
$cand[0] = 2; [0, 6], [1, 7], [2, 4], [3, 5],
$cand[1] = 3; [0, 7], [1, 2], [3, 4], [5, 6],
break; ];
case 2: $cand = $candMap[$phase % 28];
$cand[0] = 4;
$cand[1] = 5;
break;
case 3:
$cand[0] = 6;
$cand[1] = 7;
break;
case 4:
$cand[0] = 0;
$cand[1] = 2;
break;
case 5:
$cand[0] = 1;
$cand[1] = 3;
break;
case 6:
$cand[0] = 4;
$cand[1] = 6;
break;
case 7:
$cand[0] = 5;
$cand[1] = 7;
break;
case 8:
$cand[0] = 0;
$cand[1] = 3;
break;
case 9:
$cand[0] = 1;
$cand[1] = 6;
break;
case 10:
$cand[0] = 2;
$cand[1] = 5;
break;
case 11:
$cand[0] = 4;
$cand[1] = 7;
break;
case 12:
$cand[0] = 0;
$cand[1] = 4;
break;
case 13:
$cand[0] = 1;
$cand[1] = 5;
break;
case 14:
$cand[0] = 2;
$cand[1] = 6;
break;
case 15:
$cand[0] = 3;
$cand[1] = 7;
break;
case 16:
$cand[0] = 0;
$cand[1] = 5;
break;
case 17:
$cand[0] = 1;
$cand[1] = 4;
break;
case 18:
$cand[0] = 2;
$cand[1] = 7;
break;
case 19:
$cand[0] = 3;
$cand[1] = 6;
break;
case 20:
$cand[0] = 0;
$cand[1] = 6;
break;
case 21:
$cand[0] = 1;
$cand[1] = 7;
break;
case 22:
$cand[0] = 2;
$cand[1] = 4;
break;
case 23:
$cand[0] = 3;
$cand[1] = 5;
break;
case 24:
$cand[0] = 0;
$cand[1] = 7;
break;
case 25:
$cand[0] = 1;
$cand[1] = 2;
break;
case 26:
$cand[0] = 3;
$cand[1] = 4;
break;
case 27:
$cand[0] = 5;
$cand[1] = 6;
break;
}
if ($phase >= 28) { if ($phase >= 28) {
$temp = $cand[0]; $cand = [$cand[1], $cand[0]];
$cand[0] = $cand[1];
$cand[1] = $temp;
} }
break; break;
case 4: case 4:
//본선 //본선
switch ($phase % 6) { $candMap = [
case 0: [0, 1], [2, 3],
$cand[0] = 0; [0, 2], [1, 3],
$cand[1] = 1; [0, 3], [1, 2],
break; ];
case 1: $cand = $candMap[$phase % 6];
$cand[0] = 2;
$cand[1] = 3;
break;
case 2:
$cand[0] = 0;
$cand[1] = 2;
break;
case 3:
$cand[0] = 1;
$cand[1] = 3;
break;
case 4:
$cand[0] = 0;
$cand[1] = 3;
break;
case 5:
$cand[0] = 1;
$cand[1] = 2;
break;
}
break; break;
} }
return $cand; return $cand;
@@ -922,29 +767,14 @@ function finalFight($tnmt_type, $tnmt, $phase, $type)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
switch ($type) { [$offset, $turn, $next] = [
case 16: 16 => [20, 7, 7],
$offset = 20; 8 => [30, 3, 8],
$turn = 7; 4 => [40, 1, 9],
$next = 7; 2 => [50, 0, 0],
break; ][$type] ?? [0, 0, 0];
case 8: if ($offset === 0) {
$offset = 30; throw new MustNotBeReachedException();
$turn = 3;
$next = 8;
break;
case 4:
$offset = 40;
$turn = 1;
$next = 9;
break;
case 2:
$offset = 50;
$turn = 0;
$next = 0;
break;
default:
throw new MustNotBeReachedException();
} }
$grp = $phase + $offset; $grp = $phase + $offset;
@@ -982,29 +812,18 @@ function setGift($tnmt_type, $tnmt, $phase)
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
$admin = $gameStor->getValues(['year', 'month', 'develcost']); $admin = $gameStor->getValues(['year', 'month', 'develcost', 'last_tournament_betting_id']);
$resultHelper = []; $resultHelper = [];
switch ($tnmt_type) { [$tp, $tp2] = [
case 0: 0 => ['전력전', 'tt'],
$tp = "전력전"; 1 => ['통솔전', 'tl'],
$tp2 = "tt"; 2 => ['일기토', 'ts'],
break; 3 => ['설전', 'ti'],
case 1: ][$tnmt_type] ?? [null, null];
$tp = "통솔전"; if($tp === null || $tp2 === null){
$tp2 = "tl"; throw new MustNotBeReachedException();
break;
case 2:
$tp = "일기토";
$tp2 = "ts";
break;
case 3:
$tp = "설전";
$tp2 = "ti";
break;
default:
throw new MustNotBeReachedException();
} }
//16강자 명성 돈 //16강자 명성 돈
@@ -1063,7 +882,7 @@ function setGift($tnmt_type, $tnmt, $phase)
//포상 장수 이름, 금액 //포상 장수 이름, 금액
$resultHelper[$generalID]['reward'] += $cost; $resultHelper[$generalID]['reward'] += $cost;
$resultHelper[$generalID]['msg'] = "<span class='ev_highlight'>4강 진출</span>"; $resultHelper[$generalID]['msg'] = "<span class='ev_highlight'>4강 진출</span>";
General::createGeneralObjFromDB($generalID)->increaseInheritancePoint('tournament', 10); General::createObjFromDB($generalID)->increaseInheritancePoint(InheritanceKey::tournament, 10);
} }
//결승자 명성 돈 //결승자 명성 돈
$cost = $admin['develcost'] * 6; $cost = $admin['develcost'] * 6;
@@ -1108,7 +927,7 @@ function setGift($tnmt_type, $tnmt, $phase)
} }
//자동진행 끝 //자동진행 끝
$gameStor->tnmt_auto = 0; $gameStor->tnmt_auto = false;
//장수열전 기록 //장수열전 기록
/** @var ActionLogger */ /** @var ActionLogger */
@@ -1127,7 +946,7 @@ function setGift($tnmt_type, $tnmt, $phase)
$winnerLogger->pushGlobalHistoryLog("<B><b>【대회】</b></><C>{$tp}</> 대회에서 <Y>{$winner['name']}</>{$josaYiWinner} <C>우승</>, <Y>{$runnerUp['name']}</>{$josaYiRunnerUp} <C>준우승</>을 차지하여 천하에 이름을 떨칩니다!", ActionLogger::EVENT_YEAR_MONTH); $winnerLogger->pushGlobalHistoryLog("<B><b>【대회】</b></><C>{$tp}</> 대회에서 <Y>{$winner['name']}</>{$josaYiWinner} <C>우승</>, <Y>{$runnerUp['name']}</>{$josaYiRunnerUp} <C>준우승</>을 차지하여 천하에 이름을 떨칩니다!", ActionLogger::EVENT_YEAR_MONTH);
$winnerLogger->pushGlobalHistoryLog("<B><b>【대회】</b></><C>{$tp}</> 대회의 <S>우승자</>에게는 <C>{$winnerRewardText}</>, <S>준우승자</>에겐 <C>{$runnerUpRewardText}</>의 <S>상금</>과 약간의 <S>명성</>이 주어집니다!", ActionLogger::EVENT_YEAR_MONTH); $winnerLogger->pushGlobalHistoryLog("<B><b>【대회】</b></><C>{$tp}</> 대회의 <S>우승자</>에게는 <C>{$winnerRewardText}</>, <S>준우승자</>에겐 <C>{$runnerUpRewardText}</>의 <S>상금</>과 약간의 <S>명성</>이 주어집니다!", ActionLogger::EVENT_YEAR_MONTH);
$generalObjList = General::createGeneralObjListFromDB(array_keys($resultHelper)); $generalObjList = General::createObjListFromDB(array_keys($resultHelper));
foreach ($resultHelper as $generalID => $general) { foreach ($resultHelper as $generalID => $general) {
$rewardText = number_format($general['reward']); $rewardText = number_format($general['reward']);
@@ -1135,39 +954,19 @@ function setGift($tnmt_type, $tnmt, $phase)
$logger = $general['logger']; $logger = $general['logger'];
$logger->pushGeneralActionLog("<C>{$tp}</> 대회의 {$general['msg']}로 <C>{$rewardText}</>의 <S>상금</>, 약간의 <S>명성</> 획득!", ActionLogger::EVENT_PLAIN); $logger->pushGeneralActionLog("<C>{$tp}</> 대회의 {$general['msg']}로 <C>{$rewardText}</>의 <S>상금</>, 약간의 <S>명성</> 획득!", ActionLogger::EVENT_PLAIN);
//TODO: 토너먼트의 다른 값이 모두 sql에 직접 입력하므로 기반을 바꿔야함. //TODO: 토너먼트의 다른 값이 모두 sql에 직접 입력하므로 기반을 바꿔야함.
$generalObjList[$generalID]->increaseInheritancePoint('tournament', $general['inheritance_point']); $generalObjList[$generalID]->increaseInheritancePoint(InheritanceKey::tournament, $general['inheritance_point']);
} }
//우승자 번호
$winnerGrp = $resultHelper[$winner['no']]['grp'];
$winnerGrpNo = $resultHelper[$winner['no']]['grp_no'];
$winnerSlot = ($winnerGrp - 20) * 2 + $winnerGrpNo;
//당첨칸에 베팅한 사람들만 //당첨칸에 베팅한 사람들만
$globalBet = $db->queryFirstList('SELECT * FROM betting WHERE general_id = 0'); $bettingID = $gameStor->last_tournament_betting_id;
$globalBet = array_splice($globalBet, -16); $betting = new Betting($bettingID);
$globalBetTotal = array_sum($globalBet); $betting->giveReward([$winner['no']]);
$rewardRate = round($globalBetTotal / max($globalBet[$winnerSlot], 1), 2);
$betKey = "bet{$winnerSlot}";
$gambleResult = Util::convertArrayToDict($db->query('SELECT general_id, %b as bet FROM betting WHERE %b > 0 AND general_id > 0', $betKey, $betKey), 'general_id');
foreach (General::createGeneralObjListFromDB(Util::squeezeFromArray($gambleResult, 'general_id'), ['gold', 'npc'], 1) as $gambler) {
$reward = Util::round($gambleResult[$gambler->getID()]['bet'] * $rewardRate);
$gambler->increaseVar('gold', $reward);
if (($gambler->getNPCType() == 0) || ($gambler->getNPCType() == 1 && $gambler->getRankVar('betgold', 0) > 0)) {
$gambler->increaseRankVar('betwingold', $reward);
$gambler->increaseRankVar('betwin', 1);
}
$rewardText = number_format($reward);
$gambler->getLogger()->pushGeneralActionLog("<C>{$tp}</> 대회의 베팅 당첨으로 <C>{$rewardText}</>의 <S>금</> 획득!", ActionLogger::EVENT_PLAIN);
$gambler->applyDB($db);
}
} }
function setRefund() function setRefund()
{ {
$db = DB::db(); $db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env'); $gameStor = KVStorage::getStorage($db, 'game_env');
//16강자 명성 돈 //16강자 명성 돈
@@ -1178,12 +977,16 @@ function setRefund()
], 'no IN %li', $generalIDList); ], 'no IN %li', $generalIDList);
//베팅금 환수 //베팅금 환수
$db->update(['general', [ $bettingID = $gameStor->last_tournament_betting_id ?? 0;
'gold' => $db->sqleval('gold + (SELECT bet0+bet1+bet2+bet3+bet4+bet5+bet6+bet7+bet8+bet9+bet10+bet11+bet12+bet13+bet14+bet15 FROM betting WHERE general_id = general.no)') if ($bettingID != 0) {
]], true); $betting = new Betting($bettingID);
if (!$betting->getInfo()->finished) {
$betting->giveReward([-1]);
}
}
//자동진행 끝 //자동진행 끝
$gameStor->tnmt_auto = 0; $gameStor->tnmt_auto = false;
} }
//10차이 1.1, 50 차이 1.17, 100차이 1.2 //10차이 1.1, 50 차이 1.17, 100차이 1.2
@@ -1214,19 +1017,15 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type)
$turn = 100; $turn = 100;
} }
[$tp, $tp2] = [
0 => ['total', 'tt'],
1 => ['leadership', 'tl'],
2 => ['strength', 'ts'],
3 => ['intel', 'ti'],
][$tnmt_type] ?? [null, null];
if ($tnmt_type == 1) { if($tp === null || $tp2 === null){
$tp = "leadership"; throw new MustNotBeReachedException($tnmt_type);
$tp2 = "tl";
} elseif ($tnmt_type == 2) {
$tp = "strength";
$tp2 = "ts";
} elseif ($tnmt_type == 3) {
$tp = "intel";
$tp2 = "ti";
} else /*$tnmt_type == 0*/ {
$tp = "total";
$tp2 = "tt";
} }
$e1 = $energy1 = Util::round($gen1[$tp] * getLog($gen1['lvl'], $gen2['lvl']) * 10); $e1 = $energy1 = Util::round($gen1[$tp] * getLog($gen1['lvl'], $gen2['lvl']) * 10);
@@ -1333,303 +1132,70 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type)
} // 10~50 } // 10~50
$critical1 = 0; $critical1 = 0;
$critical2 = 0; $critical2 = 0;
$crticialSkillMap = [
0 => ['전력', '집중'],
1 => ['봉시진', '어린진'],
2 => ['삼단', '나선'],
3 => ['독설', '논파'],
];
$fatalitySkillMap = [
0 => '압도',
1 => '팔문금쇄진',
2 => '일격 필살',
3 => '모독 욕설'
];
$skillMap = [
0 => ['참격', '집중', '역공', '반격', '선제', '도발'],
1 => ['추행진', '학익진', '장사진', '형액진', '기형진', '구행진'],
2 => ['기합', '기염', '반격', '역공', '삼단', '나선'],
3 => ['논파', '항변', '반론', '반박', '도발', '면박'],
];
//막판 분노 //막판 분노
$ratio = rand() % 300; $ratio = rand() % 300;
if ($e1 / 5 > $energy1 && $damage1 > $damage2 && $gen1[$tp] >= $ratio) { if ($e1 / 5 > $energy1 && $damage1 > $damage2 && $gen1[$tp] >= $ratio) {
$damage2 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500% $damage2 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
$critical1 = 1; $critical1 = 1;
if ($tnmt_type == 0) { $str = Util::choiceRandom($crticialSkillMap[$tnmt_type]);
switch (rand() % 2) {
case 0:
$str = "전력";
break;
case 1:
$str = "집중";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 2) {
case 0:
$str = "봉시진";
break;
case 1:
$str = "어린진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 2) {
case 0:
$str = "삼단";
break;
case 1:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 2) {
case 0:
$str = "독설";
break;
case 1:
$str = "논파";
break;
}
}
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 분노의 <M>{$str}</> 공격!"; $log[] = "<S>●</> <Y>{$gen1['name']}</>의 분노의 <M>{$str}</> 공격!";
} }
$ratio = rand() % 300; $ratio = rand() % 300;
if ($e2 / 5 > $energy2 && $damage2 > $damage1 && $gen2[$tp] >= $ratio) { if ($e2 / 5 > $energy2 && $damage2 > $damage1 && $gen2[$tp] >= $ratio) {
$damage1 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500% $damage1 *= Util::round((rand() % 301 + 200) / 100); // 200 ~ 500%
$critical2 = 1; $critical2 = 1;
if ($tnmt_type == 0) {
switch (rand() % 2) { $str = Util::choiceRandom($crticialSkillMap[$tnmt_type]);
case 0:
$str = "전력";
break;
case 1:
$str = "집중";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 2) {
case 0:
$str = "봉시진";
break;
case 1:
$str = "어린진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 2) {
case 0:
$str = "삼단";
break;
case 1:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 2) {
case 0:
$str = "독설";
break;
case 1:
$str = "논파";
break;
}
}
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 분노의 <M>{$str}</> 공격!"; $log[] = "<S>●</> <Y>{$gen2['name']}</>의 분노의 <M>{$str}</> 공격!";
} }
//1합 승부 //1합 승부
if ($phase == 1) { if ($phase == 1) {
$ratio = rand() % 400; $ratio = rand() % 400;
if ($gen1[$tp] * 0.9 > $gen2[$tp] && $gen1[$tp] >= $ratio) { if ($gen1[$tp] * 0.9 > $gen2[$tp] && $gen1[$tp] >= $ratio) {
$damage1 = 0; $damage1 = 0;
$damage2 = $e2; $damage2 = $e2;
if ($tnmt_type == 0) { $log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>{$fatalitySkillMap[$tnmt_type]}</>!";
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>압도</>!";
} elseif ($tnmt_type == 1) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>팔문금쇄진</>!";
} elseif ($tnmt_type == 2) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>일격 필살</>!";
} elseif ($tnmt_type == 3) {
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>모독 욕설</>!";
}
} }
if ($gen2[$tp] * 0.9 > $gen1[$tp] && $gen2[$tp] >= $ratio) { if ($gen2[$tp] * 0.9 > $gen1[$tp] && $gen2[$tp] >= $ratio) {
$damage2 = 0; $damage2 = 0;
$damage1 = $e1; $damage1 = $e1;
if ($tnmt_type == 0) { $log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>{$fatalitySkillMap[$tnmt_type]}</>!";
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>압도</>!";
} elseif ($tnmt_type == 1) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>팔문금쇄진</>!";
} elseif ($tnmt_type == 2) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>일격 필살</>!";
} elseif ($tnmt_type == 3) {
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>모독 욕설</>!";
}
} }
} else { } else {
$ratio = rand() % 1000; $ratio = rand() % 1000;
if ($critical1 == 0 && $gen1[$tp] >= $ratio) { if ($critical1 == 0 && $gen1[$tp] >= $ratio) {
$damage2 *= Util::randRangeInt(150, 300) / 100; // 150 ~ 300% $damage2 *= Util::randRangeInt(150, 300) / 100; // 150 ~ 300%
$critical1 = 1; $critical1 = 1;
if ($tnmt_type == 0) { $str = Util::choiceRandom($skillMap[$tnmt_type]);
switch (rand() % 6) {
case 0:
$str = "참격";
break;
case 1:
$str = "집중";
break;
case 2:
$str = "역공";
break;
case 3:
$str = "반격";
break;
case 4:
$str = "선제";
break;
case 5:
$str = "도발";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 6) {
case 0:
$str = "추행진";
break;
case 1:
$str = "학익진";
break;
case 2:
$str = "장사진";
break;
case 3:
$str = "형액진";
break;
case 4:
$str = "기형진";
break;
case 5:
$str = "구행진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 6) {
case 0:
$str = "기합";
break;
case 1:
$str = "기염";
break;
case 2:
$str = "반격";
break;
case 3:
$str = "역공";
break;
case 4:
$str = "삼단";
break;
case 5:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 6) {
case 0:
$str = "논파";
break;
case 1:
$str = "항변";
break;
case 2:
$str = "반론";
break;
case 3:
$str = "반박";
break;
case 4:
$str = "도발";
break;
case 5:
$str = "면박";
break;
}
}
$log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>{$str}</>!"; $log[] = "<S>●</> <Y>{$gen1['name']}</>의 <M>{$str}</>!";
} }
$ratio = rand() % 1000; $ratio = rand() % 1000;
if ($critical2 == 0 && $gen2[$tp] >= $ratio) { if ($critical2 == 0 && $gen2[$tp] >= $ratio) {
$damage1 *= Util::randRangeInt(150, 300) / 100; // 150 ~ 300% $damage1 *= Util::randRangeInt(150, 300) / 100; // 150 ~ 300%
$critical2 = 1; $critical2 = 1;
if ($tnmt_type == 0) { $str = Util::choiceRandom($skillMap[$tnmt_type]);
switch (rand() % 6) {
case 0:
$str = "참격";
break;
case 1:
$str = "집중";
break;
case 2:
$str = "역공";
break;
case 3:
$str = "반격";
break;
case 4:
$str = "선제";
break;
case 5:
$str = "도발";
break;
}
} elseif ($tnmt_type == 1) {
switch (rand() % 6) {
case 0:
$str = "추행진";
break;
case 1:
$str = "학익진";
break;
case 2:
$str = "장사진";
break;
case 3:
$str = "형액진";
break;
case 4:
$str = "기형진";
break;
case 5:
$str = "구행진";
break;
}
} elseif ($tnmt_type == 2) {
switch (rand() % 6) {
case 0:
$str = "기합";
break;
case 1:
$str = "기염";
break;
case 2:
$str = "반격";
break;
case 3:
$str = "역공";
break;
case 4:
$str = "삼단";
break;
case 5:
$str = "나선";
break;
}
} elseif ($tnmt_type == 3) {
switch (rand() % 6) {
case 0:
$str = "논파";
break;
case 1:
$str = "항변";
break;
case 2:
$str = "반론";
break;
case 3:
$str = "반박";
break;
case 4:
$str = "도발";
break;
case 5:
$str = "면박";
break;
}
}
$log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>{$str}</>!"; $log[] = "<S>●</> <Y>{$gen2['name']}</>의 <M>{$str}</>!";
} }
} }
BIN
View File
Binary file not shown.
-684
View File
@@ -1,684 +0,0 @@
상성 이름 사진 국가 도시 통 무 지 급 출생 사망 꿈 특기
1, "소제1",1001, 0, "낙양", 20, 11, 48, 0, 168, 190, "유지", "-"); $gencount++;
1, "헌제",1002, 0, "낙양", 17, 13, 61, 0, 170, 250, "안전", "-", "한 왕조는 이대로 끝나는 것인가..."); $gencount++;
999, "사마휘",1003, 0, "양양", 71, 11, 96, 0, 173, 234, "은둔", "신산", "좋지, 좋아~"); $gencount++;
999, "우길",1004, 0, "업", 17, 13, 83, 0, 131, 200, "은둔", "신산"); $gencount++;
999, "화타",1005, 0, "낙양", 53, 25, 70, 0, 151, 220, "은둔", "의술", "아픈 사람들은 모두 내게 오시오. 껄껄껄."); $gencount++;
999, "길평",1006, 0, "허창", 27, 15, 72, 0, 158, 200, "은둔", "의술"); $gencount++;
29, "가규",1007, 0, "낙양", 55, 55, 74, 0, 177, 231, "재간", "-"); $gencount++;
136, "가범",1008, 0, "낙양", 58, 48, 73, 0, 202, 237, "유지", "-"); $gencount++;
49, "가비능",1009, 0, "낙양", 58, 83, 32, 0, 172, 235, "정복", "-"); $gencount++;
31, "가충",1010, 0, "낙양", 50, 25, 87, 0, 217, 282, "출세", "-"); $gencount++;
20, "가후",1011, 0, "낙양", 69, 30, 94, 0, 147, 223, "할거", "귀병"); $gencount++;
73, "간옹",1012, 0, "낙양", 31, 33, 70, 0, 164, 225, "안전", "경작"); $gencount++;
129, "감녕",1013, 0, "낙양", 78, 95, 71, 0, 174, 222, "출세", "무쌍"); $gencount++;
127, "감택",1014, 0, "낙양", 62, 44, 79, 0, 182, 243, "유지", "-"); $gencount++;
60, "강단",1015, 0, "낙양", 41, 73, 43, 0, 168, 230, "재간", "-"); $gencount++;
73, "강유",1016, 0, "낙양", 95, 90, 94, 0, 202, 264, "왕좌", "집중"); $gencount++;
102, "고간",1017, 0, "낙양", 60, 57, 51, 0, 168, 206, "유지", "-"); $gencount++;
27, "고람",1018, 0, "낙양", 72, 67, 59, 0, 159, 201, "출세", "기병"); $gencount++;
69, "고상",1019, 0, "낙양", 41, 40, 38, 0, 194, 252, "재간", "-"); $gencount++;
144, "고순",1020, 0, "낙양", 79, 82, 65, 0, 162, 198, "의협", "기병"); $gencount++;
7, "고승",1021, 0, "낙양", 42, 73, 24, 0, 145, 185, "출세", "-"); $gencount++;
120, "고옹",1022, 0, "낙양", 57, 21, 79, 0, 168, 243, "출세", "-"); $gencount++;
63, "고정",1023, 0, "낙양", 67, 65, 55, 0, 190, 251, "정복", "-"); $gencount++;
53, "고패",1024, 0, "낙양", 53, 56, 28, 0, 170, 212, "유지", "-"); $gencount++;
74, "공도",1025, 0, "낙양", 26, 73, 19, 0, 164, 200, "재간", "-"); $gencount++;
142, "공손강",1026, 0, "낙양", 64, 72, 61, 0, 172, 210, "정복", "-"); $gencount++;
142, "공손공",1027, 0, "낙양", 68, 41, 75, 0, 174, 238, "정복", "-"); $gencount++;
142, "공손도",1028, 0, "낙양", 62, 72, 41, 0, 154, 204, "정복", "기병"); $gencount++;
65, "공손범",1029, 0, "낙양", 61, 67, 61, 0, 158, 199, "출세", "-"); $gencount++;
65, "공손속",1030, 0, "낙양", 60, 76, 41, 0, 176, 199, "정복", "-"); $gencount++;
10, "공손연",1031, 0, "낙양", 74, 79, 64, 0, 205, 238, "패권", "돌격"); $gencount++;
65, "공손월",1032, 0, "낙양", 47, 63, 46, 0, 160, 192, "정복", "-"); $gencount++;
65, "공손찬",1033, 0, "낙양", 61, 87, 67, 0, 152, 199, "패권", "기병"); $gencount++;
43, "공융",1034, 0, "낙양", 63, 48, 85, 0, 153, 208, "왕좌", "경작"); $gencount++;
35, "공주",1035, 0, "낙양", 64, 35, 78, 0, 151, 194, "재간", "-"); $gencount++;
83, "공지",1036, 0, "낙양", 57, 54, 64, 0, 178, 242, "대의", "-"); $gencount++;
26, "곽가",1037, 0, "낙양", 47, 23, 99, 0, 170, 207, "패권", "귀모"); $gencount++;
111, "곽도",1038, 0, "낙양", 63, 67, 81, 0, 155, 205, "재간", "-"); $gencount++;
2, "곽사",1039, 0, "낙양", 58, 67, 31, 0, 146, 197, "패권", "-"); $gencount++;
80, "곽유지",1040, 0, "낙양", 37, 22, 71, 0, 190, 259, "재간", "상재"); $gencount++;
67, "곽익",1041, 0, "낙양", 67, 60, 67, 0, 207, 270, "재간", "-"); $gencount++;
67, "곽준",1042, 0, "낙양", 76, 69, 73, 0, 178, 217, "출세", "-"); $gencount++;
27, "곽혁",1043, 0, "낙양", 40, 29, 80, 0, 187, 228, "안전", "-"); $gencount++;
20, "곽회",1044, 0, "낙양", 77, 75, 71, 0, 187, 255, "정복", "-"); $gencount++;
39, "관구검",1045, 0, "낙양", 72, 68, 77, 0, 202, 255, "대의", "-"); $gencount++;
76, "관색",1046, 0, "낙양", 69, 85, 67, 0, 200, 239, "의협", "징병"); $gencount++;
76, "관우",1047, 0, "낙양", 96, 98, 80, 0, 162, 219, "의협", "위압"); $gencount++;
76, "관이",1048, 0, "낙양", 48, 60, 58, 0, 219, 263, "안전", "-"); $gencount++;
76, "관통",1049, 0, "낙양", 49, 63, 60, 0, 218, 259, "대의", "-"); $gencount++;
76, "관평",1050, 0, "낙양", 77, 80, 70, 0, 186, 219, "의협", "보병"); $gencount++;
7, "관해",1051, 0, "낙양", 66, 90, 35, 0, 160, 193, "출세", "-"); $gencount++;
76, "관흥",1052, 0, "낙양", 69, 84, 72, 0, 199, 234, "의협", "돌격"); $gencount++;
40, "괴량",1053, 0, "낙양", 41, 28, 81, 0, 155, 204, "안전", "신중"); $gencount++;
40, "괴월",1054, 0, "낙양", 26, 30, 84, 0, 157, 214, "유지", "귀병"); $gencount++;
98, "교모",1055, 0, "낙양", 59, 58, 61, 0, 150, 191, "안전", "-"); $gencount++;
98, "교현",1056, 0, "낙양", 50, 18, 60, 0, 158, 210, "재간", "-"); $gencount++;
6, "구역거",1057, 0, "낙양", 51, 72, 49, 0, 152, 193, "안전", "-"); $gencount++;
80, "극정",1058, 0, "낙양", 38, 25, 75, 0, 208, 278, "유지", "-"); $gencount++;
46, "금선",1059, 0, "낙양", 55, 49, 36, 0, 155, 208, "할거", "-"); $gencount++;
62, "금환삼결",1060, 0, "낙양", 46, 76, 17, 0, 192, 225, "출세", "-"); $gencount++;
141, "기령",1061, 0, "낙양", 76, 81, 33, 0, 155, 199, "대의", "무쌍"); $gencount++;
122, "낙통",1062, 0, "낙양", 57, 44, 69, 0, 193, 228, "유지", "-"); $gencount++;
124, "노숙1",1063, 0, "낙양", 90, 42, 94, 0, 172, 217, "왕좌", "상재"); $gencount++;
75, "노식",1064, 0, "낙양", 91, 54, 80, 0, 139, 192, "왕좌", "징병"); $gencount++;
59, "뇌동",1065, 0, "낙양", 70, 77, 45, 0, 172, 218, "출세", "궁병"); $gencount++;
142, "뇌박",1066, 0, "낙양", 54, 54, 33, 0, 157, 206, "유지", "-"); $gencount++;
127, "능조",1067, 0, "낙양", 67, 80, 44, 0, 165, 203, "재간", "공성"); $gencount++;
127, "능통",1068, 0, "낙양", 71, 78, 58, 0, 189, 237, "의협", "궁병"); $gencount++;
64, "단경",1069, 0, "낙양", 68, 61, 68, 0, 156, 199, "정복", "-"); $gencount++;
132, "담웅",1070, 0, "낙양", 52, 77, 19, 0, 188, 221, "출세", "-"); $gencount++;
99, "답둔",1071, 0, "낙양", 59, 71, 31, 0, 158, 207, "유지", "-"); $gencount++;
132, "당자",1072, 0, "낙양", 59, 56, 45, 0, 196, 265, "안전", "-"); $gencount++;
60, "대래동주",1073, 0, "낙양", 40, 65, 24, 0, 195, 249, "안전", "-"); $gencount++;
82, "도겸",1074, 0, "낙양", 51, 32, 61, 0, 132, 194, "할거", "인덕"); $gencount++;
120, "도준",1075, 0, "낙양", 64, 57, 50, 0, 238, 285, "안전", "-"); $gencount++;
73, "동궐",1076, 0, "낙양", 66, 50, 76, 0, 204, 271, "대의", "-"); $gencount++;
62, "동다나",1077, 0, "낙양", 51, 71, 27, 0, 189, 225, "유지", "-"); $gencount++;
2, "동민",1078, 0, "낙양", 52, 65, 49, 0, 149, 192, "안전", "-"); $gencount++;
21, "동소",1079, 0, "낙양", 46, 46, 62, 0, 156, 236, "패권", "-"); $gencount++;
127, "동습",1080, 0, "낙양", 53, 64, 32, 0, 169, 215, "출세", "-"); $gencount++;
89, "동승",1081, 0, "낙양", 75, 66, 65, 0, 154, 200, "왕좌", "-"); $gencount++;
78, "동윤",1082, 0, "낙양", 64, 26, 78, 0, 192, 246, "왕좌", "-"); $gencount++;
2, "동탁",1083, 0, "낙양", 87, 91, 54, 0, 139, 192, "패권", "기병"); $gencount++;
66, "동화",1084, 0, "낙양", 48, 64, 53, 0, 168, 219, "대의", "-"); $gencount++;
32, "두예",1085, 0, "낙양", 88, 80, 84, 0, 222, 284, "정복", "-"); $gencount++;
7, "등무",1086, 0, "낙양", 43, 74, 19, 0, 147, 185, "정복", "-"); $gencount++;
41, "등애",1087, 0, "낙양", 94, 82, 92, 0, 197, 264, "패권", "신산"); $gencount++;
116, "등윤",1088, 0, "낙양", 34, 42, 68, 0, 194, 256, "안전", "-"); $gencount++;
73, "등지",1089, 0, "낙양", 74, 51, 80, 0, 182, 251, "할거", "경작"); $gencount++;
41, "등충",1090, 0, "낙양", 60, 82, 55, 0, 230, 264, "출세", "-"); $gencount++;
54, "등현",1091, 0, "낙양", 65, 59, 61, 0, 188, 248, "출세", "-"); $gencount++;
29, "마균",1092, 0, "낙양", 33, 38, 80, 0, 200, 259, "안전", "-"); $gencount++;
71, "마대",1093, 0, "낙양", 77, 79, 49, 0, 183, 246, "대의", "기병"); $gencount++;
70, "마등",1094, 0, "낙양", 80, 87, 56, 0, 149, 211, "왕좌", "기병"); $gencount++;
80, "마속",1095, 0, "낙양", 73, 64, 82, 0, 190, 228, "패권", "집중"); $gencount++;
77, "마량",1096, 0, "낙양", 57, 25, 87, 0, 187, 225, "왕좌", "-"); $gencount++;
48, "마완",1097, 0, "낙양", 49, 64, 26, 0, 170, 211, "안전", "기병"); $gencount++;
19, "마준",1098, 0, "낙양", 45, 63, 62, 0, 196, 260, "안전", "-"); $gencount++;
71, "마철",1099, 0, "낙양", 71, 60, 31, 0, 179, 211, "대의", "기병"); $gencount++;
70, "마초",1100, 0, "낙양", 78, 97, 40, 0, 176, 226, "대의", "기병"); $gencount++;
131, "마충1",1101, 0, "낙양", 67, 62, 51, 0, 186, 222, "재간", "-"); $gencount++;
69, "마충2",1102, 0, "낙양", 61, 68, 51, 0, 187, 249, "출세", "-"); $gencount++;
71, "마휴",1103, 0, "낙양", 71, 60, 32, 0, 178, 211, "대의", "기병"); $gencount++;
116, "만총",1104, 0, "낙양", 79, 40, 78, 0, 170, 242, "할거", "신중"); $gencount++;
51, "망아장",1105, 0, "낙양", 29, 64, 20, 0, 191, 225, "출세", "-"); $gencount++;
44, "맹달",1106, 0, "낙양", 70, 66, 72, 0, 172, 228, "할거", "귀병"); $gencount++;
60, "맹우",1107, 0, "낙양", 63, 79, 26, 0, 190, 251, "정복", "-"); $gencount++;
60, "맹획",1108, 0, "낙양", 78, 92, 50, 0, 186, 245, "왕좌", "격노"); $gencount++;
29, "모개",1109, 0, "낙양", 46, 56, 56, 0, 161, 216, "대의", "-"); $gencount++;
51, "목록대왕",1110, 0, "낙양", 58, 71, 65, 0, 184, 225, "재간", "척사"); $gencount++;
96, "목순",1111, 0, "낙양", 17, 21, 68, 0, 157, 191, "왕좌", "-"); $gencount++;
43, "무안국",1112, 0, "낙양", 51, 73, 18, 0, 156, 191, "재간", "-"); $gencount++;
28, "문빙",1113, 0, "낙양", 70, 77, 43, 0, 178, 237, "유지", "-"); $gencount++;
38, "문앙",1114, 0, "낙양", 71, 91, 46, 0, 222, 285, "대의", "-"); $gencount++;
102, "문추",1115, 0, "낙양", 72, 94, 25, 0, 161, 200, "출세", "무쌍"); $gencount++;
38, "문흠",1116, 0, "낙양", 76, 77, 43, 0, 200, 258, "대의", "-"); $gencount++;
49, "미당대왕",1117, 0, "낙양", 64, 75, 32, 0, 202, 260, "유지", "-"); $gencount++;
108, "미방",1118, 0, "낙양", 58, 65, 37, 0, 169, 222, "패권", "징병"); $gencount++;
77, "미축",1119, 0, "낙양", 26, 30, 65, 0, 165, 220, "왕좌", "상재"); $gencount++;
94, "반봉",1120, 0, "낙양", 61, 75, 17, 0, 155, 191, "출세", "-"); $gencount++;
44, "반준",1121, 0, "낙양", 41, 21, 67, 0, 174, 239, "안전", "-"); $gencount++;
65, "방덕",1122, 0, "낙양", 76, 90, 67, 0, 170, 219, "의협", "기병"); $gencount++;
73, "방통",1123, 0, "낙양", 86, 41, 97, 0, 179, 214, "패권", "반계"); $gencount++;
65, "방회",1124, 0, "낙양", 25, 33, 59, 0, 205, 272, "안전", "-"); $gencount++;
68, "배원소",1125, 0, "낙양", 45, 69, 33, 0, 169, 200, "재간", "-"); $gencount++;
78, "번건",1126, 0, "낙양", 28, 31, 68, 0, 205, 270, "대의", "-"); $gencount++;
149, "번주",1127, 0, "낙양", 67, 77, 21, 0, 149, 192, "할거", "-"); $gencount++;
72, "법정",1128, 0, "낙양", 81, 29, 93, 0, 176, 220, "패권", "신산"); $gencount++;
8, "변희",1129, 0, "낙양", 65, 65, 27, 0, 169, 200, "안전", "-"); $gencount++;
121, "보질",1130, 0, "낙양", 58, 28, 77, 0, 177, 247, "유지", "-"); $gencount++;
113, "복양흥",1131, 0, "낙양", 58, 51, 71, 0, 224, 264, "유지", "-"); $gencount++;
110, "봉기",1132, 0, "낙양", 68, 52, 80, 0, 153, 202, "패권", "집중"); $gencount++;
74, "부동",1133, 0, "낙양", 58, 69, 69, 0, 183, 222, "대의", "-"); $gencount++;
108, "부사인",1134, 0, "낙양", 54, 59, 51, 0, 182, 222, "출세", "-"); $gencount++;
38, "부손",1135, 0, "낙양", 24, 43, 68, 0, 162, 230, "안전", "-"); $gencount++;
74, "부첨",1136, 0, "낙양", 61, 74, 45, 0, 216, 263, "대의", "-"); $gencount++;
66, "비시",1137, 0, "낙양", 18, 36, 61, 0, 176, 240, "재간", "-"); $gencount++;
141, "비연",1138, 0, "낙양", 66, 65, 53, 0, 196, 238, "출세", "-"); $gencount++;
77, "비위",1139, 0, "낙양", 72, 26, 73, 0, 193, 253, "대의", "-"); $gencount++;
144, "사광",1140, 0, "낙양", 57, 49, 66, 0, 175, 235, "안전", "-"); $gencount++;
71, "사마가",1141, 0, "낙양", 61, 85, 18, 0, 167, 222, "정복", "돌격"); $gencount++;
20, "사마랑",1142, 0, "낙양", 25, 32, 63, 0, 171, 217, "대의", "-"); $gencount++;
24, "사마망",1143, 0, "낙양", 71, 61, 65, 0, 205, 271, "정복", "-"); $gencount++;
24, "사마부",1144, 0, "낙양", 55, 31, 73, 0, 180, 272, "대의", "-"); $gencount++;
31, "사마사",1145, 0, "낙양", 87, 64, 91, 0, 208, 255, "정복", "-"); $gencount++;
31, "사마소",1146, 0, "낙양", 93, 63, 84, 0, 211, 265, "정복", "-"); $gencount++;
31, "사마염",1147, 0, "낙양", 92, 78, 72, 0, 236, 290, "패권", "-"); $gencount++;
30, "사마유",1148, 0, "낙양", 62, 45, 79, 0, 248, 283, "왕좌", "-"); $gencount++;
31, "사마의",1149, 0, "낙양", 98, 67, 98, 0, 179, 251, "패권", "반계"); $gencount++;
139, "사섭",1150, 0, "낙양", 63, 61, 71, 0, 137, 226, "안전", "-"); $gencount++;
139, "사일",1151, 0, "낙양", 59, 44, 68, 0, 153, 230, "유지", "-"); $gencount++;
132, "사정",1152, 0, "낙양", 67, 71, 20, 0, 178, 221, "안전", "-"); $gencount++;
146, "사지",1153, 0, "낙양", 61, 49, 70, 0, 163, 227, "안전", "-"); $gencount++;
144, "사휘",1154, 0, "낙양", 67, 71, 61, 0, 165, 227, "유지", "-"); $gencount++;
35, "서막",1155, 0, "낙양", 56, 41, 72, 0, 171, 249, "유지", "-"); $gencount++;
76, "서서",1156, 0, "낙양", 90, 70, 96, 0, 178, 232, "의협", "귀병"); $gencount++;
124, "서성",1157, 0, "낙양", 83, 76, 83, 0, 177, 234, "대의", "-"); $gencount++;
142, "서영",1158, 0, "낙양", 47, 63, 33, 0, 147, 191, "안전", "-"); $gencount++;
23, "서질",1159, 0, "낙양", 55, 73, 34, 0, 207, 253, "재간", "-"); $gencount++;
23, "서황",1160, 0, "낙양", 79, 89, 68, 0, 165, 228, "의협", "필살"); $gencount++;
32, "석포",1161, 0, "낙양", 71, 63, 59, 0, 214, 272, "정복", "-"); $gencount++;
131, "설영",1162, 0, "낙양", 46, 23, 64, 0, 223, 282, "유지", "-"); $gencount++;
128, "설종",1163, 0, "낙양", 27, 33, 67, 0, 187, 243, "유지", "-"); $gencount++;
69, "성의",1164, 0, "낙양", 45, 64, 22, 0, 168, 211, "재간", "-"); $gencount++;
129, "소비",1165, 0, "낙양", 67, 63, 49, 0, 172, 221, "대의", "-"); $gencount++;
76, "손건",1166, 0, "낙양", 42, 33, 73, 0, 165, 215, "대의", null); $gencount++;
125, "손견",1167, 0, "낙양", 96, 95, 76, 0, 156, 192, "왕좌", "무쌍"); $gencount++;
126, "손광",1168, 0, "낙양", 63, 54, 58, 0, 186, 207, "유지", "-"); $gencount++;
125, "손권",1169, 0, "낙양", 90, 77, 83, 0, 182, 252, "할거", "수비"); $gencount++;
126, "손랑",1170, 0, "낙양", 27, 54, 28, 0, 187, 226, "안전", "-"); $gencount++;
126, "손등",1171, 0, "낙양", 52, 39, 77, 0, 209, 241, "할거", "-"); $gencount++;
125, "손량",1172, 0, "낙양", 24, 23, 79, 0, 243, 260, "할거", "-"); $gencount++;
20, "손례",1173, 0, "낙양", 64, 64, 69, 0, 180, 250, "안전", "-"); $gencount++;
124, "손소",1174, 0, "낙양", 76, 80, 68, 0, 188, 241, "정복", "-"); $gencount++;
130, "손수",1175, 0, "낙양", 67, 57, 59, 0, 235, 299, "안전", "-"); $gencount++;
126, "손유",1176, 0, "낙양", 77, 60, 67, 0, 177, 215, "정복", "-"); $gencount++;
122, "손이",1177, 0, "낙양", 57, 62, 57, 0, 223, 272, "안전", "-"); $gencount++;
126, "손정",1178, 0, "낙양", 59, 56, 62, 0, 160, 206, "유지", "-"); $gencount++;
115, "손준",1179, 0, "낙양", 59, 69, 51, 0, 219, 256, "정복", "-"); $gencount++;
7, "손중",1180, 0, "낙양", 53, 63, 24, 0, 154, 185, "안전", "-"); $gencount++;
125, "손책",1181, 0, "낙양", 96, 96, 78, 0, 175, 200, "패권", "필살"); $gencount++;
115, "손침",1182, 0, "낙양", 49, 71, 40, 0, 231, 258, "패권", "-"); $gencount++;
114, "손호",1183, 0, "낙양", 20, 78, 67, 0, 242, 284, "패권", "-"); $gencount++;
126, "손화",1184, 0, "낙양", 35, 25, 71, 0, 224, 253, "왕좌", "-"); $gencount++;
127, "손환",1185, 0, "낙양", 79, 65, 70, 0, 197, 228, "정복", "-"); $gencount++;
126, "손휴",1186, 0, "낙양", 63, 43, 64, 0, 235, 264, "정복", "-"); $gencount++;
117, "손흠",1187, 0, "낙양", 66, 63, 33, 0, 235, 280, "정복", "-"); $gencount++;
147, "송헌",1188, 0, "낙양", 42, 63, 41, 0, 157, 200, "안전", "-"); $gencount++;
95, "순우경",1189, 0, "낙양", 72, 67, 60, 0, 146, 200, "할거", "-"); $gencount++;
22, "순욱1",1190, 0, "낙양", 54, 29, 97, 0, 163, 212, "왕좌", "집중"); $gencount++;
22, "순유",1191, 0, "낙양", 73, 41, 90, 0, 157, 214, "대의", "신중"); $gencount++;
29, "신비",1192, 0, "낙양", 47, 28, 74, 0, 171, 240, "재간", "-"); $gencount++;
37, "신의",1193, 0, "낙양", 55, 61, 51, 0, 190, 252, "출세", "-"); $gencount++;
37, "신탐",1194, 0, "낙양", 56, 58, 57, 0, 188, 254, "출세", "-"); $gencount++;
85, "신평",1195, 0, "낙양", 68, 51, 75, 0, 165, 204, "왕좌", "-"); $gencount++;
102, "심배",1196, 0, "낙양", 75, 66, 68, 0, 156, 204, "패권", "귀병"); $gencount++;
126, "심영",1197, 0, "낙양", 53, 72, 51, 0, 235, 280, "재간", "-"); $gencount++;
47, "아하소과",1198, 0, "낙양", 53, 75, 15, 0, 204, 253, "안전", "척사"); $gencount++;
62, "아회남",1199, 0, "낙양", 50, 74, 30, 0, 190, 225, "출세", "척사"); $gencount++;
23, "악진",1200, 0, "낙양", 73, 67, 56, 0, 159, 218, "대의", "돌격"); $gencount++;
23, "악침",1201, 0, "낙양", 45, 52, 33, 0, 196, 257, "대의", "-"); $gencount++;
63, "악환",1202, 0, "낙양", 54, 82, 55, 0, 196, 251, "재간", "-"); $gencount++;
102, "안량",1203, 0, "낙양", 73, 93, 36, 0, 160, 200, "출세", "위압"); $gencount++;
14, "양백",1204, 0, "낙양", 55, 54, 53, 0, 171, 214, "안전", "-"); $gencount++;
92, "양봉1",1205, 0, "낙양", 57, 64, 36, 0, 153, 197, "유지", "-"); $gencount++;
91, "양봉2",1206, 0, "낙양", 62, 78, 61, 0, 191, 252, "정복", "-"); $gencount++;
13, "양송",1207, 0, "낙양", 15, 35, 34, 0, 167, 215, "안전", "-"); $gencount++;
43, "양수",1208, 0, "낙양", 18, 31, 91, 0, 175, 219, "재간", "귀병"); $gencount++;
61, "양의",1209, 0, "낙양", 67, 56, 71, 0, 190, 235, "유지", "-"); $gencount++;
141, "양조1",1210, 0, "낙양", 68, 54, 60, 0, 202, 256, "출세", "-"); $gencount++;
9, "양추1",1211, 0, "낙양", 51, 67, 16, 0, 159, 199, "정복", "-"); $gencount++;
31, "양호",1212, 0, "낙양", 91, 69, 80, 0, 221, 278, "패권", "-"); $gencount++;
53, "양회",1213, 0, "낙양", 60, 67, 40, 0, 167, 212, "출세", "-"); $gencount++;
141, "양흥",1214, 0, "낙양", 52, 68, 17, 0, 169, 211, "안전", "-"); $gencount++;
6, "어부라",1215, 0, "낙양", 78, 80, 61, 0, 150, 195, "정복", "-"); $gencount++;
64, "엄강",1216, 0, "낙양", 57, 65, 44, 0, 163, 192, "재간", "-"); $gencount++;
10, "엄백호",1217, 0, "낙양", 48, 68, 30, 0, 150, 197, "할거", "-"); $gencount++;
10, "엄여",1218, 0, "낙양", 35, 66, 24, 0, 153, 197, "할거", "-"); $gencount++;
69, "엄안",1219, 0, "낙양", 72, 84, 67, 0, 151, 222, "왕좌", "-"); $gencount++;
7, "엄정",1220, 0, "낙양", 31, 68, 49, 0, 151, 189, "출세", "-"); $gencount++;
121, "엄준",1221, 0, "낙양", 44, 24, 71, 0, 169, 246, "재간", "-"); $gencount++;
71, "여개",1222, 0, "낙양", 51, 42, 67, 0, 194, 227, "유지", "-"); $gencount++;
29, "여건",1223, 0, "낙양", 44, 68, 29, 0, 173, 238, "출세", "-"); $gencount++;
107, "여광",1224, 0, "낙양", 60, 67, 27, 0, 162, 207, "유지", "-"); $gencount++;
124, "여몽",1225, 0, "낙양", 92, 78, 93, 0, 178, 219, "패권", "궁병"); $gencount++;
123, "여범",1226, 0, "낙양", 43, 34, 71, 0, 169, 228, "할거", "-"); $gencount++;
107, "여상",1227, 0, "낙양", 62, 68, 26, 0, 164, 207, "유지", "-"); $gencount++;
105, "여위황",1228, 0, "낙양", 42, 62, 38, 0, 159, 200, "정복", "-"); $gencount++;
145, "여포",1229, 0, "낙양", 74,100, 29, 0, 156, 198, "패권", "돌격"); $gencount++;
50, "염우",1230, 0, "낙양", 58, 51, 18, 0, 209, 264, "출세", "-"); $gencount++;
40, "염유",1231, 0, "낙양", 59, 75, 51, 0, 168, 227, "출세", "-"); $gencount++;
18, "염포",1232, 0, "낙양", 33, 35, 77, 0, 163, 231, "유지", "-"); $gencount++;
40, "예형",1233, 0, "낙양", 77, 31, 95, 0, 173, 209, "은둔", "통찰"); $gencount++;
133, "오강",1234, 0, "낙양", 47, 37, 61, 0, 216, 275, "안전", "-"); $gencount++;
59, "오란",1235, 0, "낙양", 67, 75, 42, 0, 170, 218, "재간", "-"); $gencount++;
72, "오반",1236, 0, "낙양", 70, 66, 45, 0, 171, 234, "재간", "-"); $gencount++;
128, "오언",1237, 0, "낙양", 71, 60, 52, 0, 235, 297, "재간", "-"); $gencount++;
126, "오연",1238, 0, "낙양", 36, 70, 31, 0, 234, 280, "정복", "-"); $gencount++;
69, "오의",1239, 0, "낙양", 75, 72, 74, 0, 165, 237, "유지", "-"); $gencount++;
19, "오질",1240, 0, "낙양", 43, 37, 69, 0, 177, 230, "출세", "-"); $gencount++;
51, "올돌골",1241, 0, "낙양", 77, 92, 15, 0, 186, 225, "출세", "척사"); $gencount++;
52, "옹개",1242, 0, "낙양", 58, 67, 51, 0, 188, 225, "안전", "-"); $gencount++;
20, "왕경",1243, 0, "낙양", 55, 47, 65, 0, 206, 260, "재간", "-"); $gencount++;
97, "왕광",1244, 0, "낙양", 72, 67, 54, 0, 150, 190, "유지", "-"); $gencount++;
30, "왕기1",1245, 0, "낙양", 76, 62, 70, 0, 190, 261, "유지", "-"); $gencount++;
34, "왕랑",1246, 0, "낙양", 49, 29, 51, 0, 162, 228, "할거", "-"); $gencount++;
57, "왕루",1247, 0, "낙양", 40, 28, 76, 0, 173, 211, "유지", "-"); $gencount++;
76, "왕보",1248, 0, "낙양", 47, 34, 75, 0, 171, 219, "대의", "-"); $gencount++;
86, "왕수",1249, 0, "낙양", 34, 34, 67, 0, 168, 218, "재간", "-"); $gencount++;
26, "왕쌍",1250, 0, "낙양", 58, 89, 15, 0, 195, 228, "정복", "보병"); $gencount++;
46, "왕위",1251, 0, "낙양", 59, 60, 68, 0, 163, 208, "안전", "-"); $gencount++;
92, "왕윤",1252, 0, "낙양", 16, 18, 77, 0, 137, 192, "왕좌", "-"); $gencount++;
40, "왕융",1253, 0, "낙양", 62, 41, 77, 0, 234, 305, "재간", "-"); $gencount++;
32, "왕준",1254, 0, "낙양", 81, 83, 76, 0, 206, 285, "대의", "-"); $gencount++;
30, "왕찬",1255, 0, "낙양", 28, 28, 78, 0, 177, 217, "안전", "-"); $gencount++;
33, "왕창",1256, 0, "낙양", 74, 57, 52, 0, 188, 259, "정복", "-"); $gencount++;
69, "왕평",1257, 0, "낙양", 77, 76, 71, 0, 192, 248, "재간", "-"); $gencount++;
71, "왕항",1258, 0, "낙양", 51, 43, 60, 0, 184, 254, "대의", "-"); $gencount++;
33, "왕혼",1259, 0, "낙양", 69, 32, 59, 0, 223, 297, "정복", "-"); $gencount++;
71, "요립",1260, 0, "낙양", 65, 41, 84, 0, 181, 250, "출세", "-"); $gencount++;
74, "요화",1261, 0, "낙양", 67, 58, 60, 0, 170, 264, "의협", "-"); $gencount++;
22, "우금1",1262, 0, "낙양", 80, 74, 71, 0, 159, 221, "정복", "-"); $gencount++;
27, "우금2",1263, 0, "낙양", 63, 77, 37, 0, 173, 226, "대의", "-"); $gencount++;
122, "우번",1264, 0, "낙양", 23, 42, 73, 0, 164, 233, "유지", "-"); $gencount++;
126, "우전",1265, 0, "낙양", 63, 55, 41, 0, 204, 258, "안전", "-"); $gencount++;
86, "원담",1266, 0, "낙양", 67, 59, 55, 0, 173, 205, "왕좌", "-"); $gencount++;
101, "원상",1267, 0, "낙양", 54, 72, 68, 0, 179, 207, "패권", "-"); $gencount++;
101, "원소",1268, 0, "낙양", 85, 67, 76, 0, 154, 202, "패권", "위압"); $gencount++;
140, "원술",1269, 0, "낙양", 77, 59, 71, 0, 155, 199, "패권", "축성"); $gencount++;
140, "원윤",1270, 0, "낙양", 41, 34, 60, 0, 163, 199, "패권", "-"); $gencount++;
101, "원희",1271, 0, "낙양", 69, 57, 72, 0, 176, 207, "할거", "-"); $gencount++;
131, "위소",1272, 0, "낙양", 39, 24, 82, 0, 204, 273, "재간", "-"); $gencount++;
147, "위속",1273, 0, "낙양", 57, 59, 41, 0, 156, 200, "안전", "-"); $gencount++;
81, "위연",1274, 0, "낙양", 78, 94, 62, 0, 175, 234, "패권", "보병"); $gencount++;
96, "위유",1275, 0, "낙양", 53, 69, 71, 0, 151, 193, "재간", "-"); $gencount++;
76, "유기",1276, 0, "낙양", 57, 19, 73, 0, 174, 209, "왕좌", "-"); $gencount++;
36, "유대",1277, 0, "낙양", 61, 57, 62, 0, 147, 202, "재간", "-"); $gencount++;
134, "유도",1278, 0, "낙양", 35, 33, 68, 0, 168, 214, "재간", "-"); $gencount++;
46, "유벽",1279, 0, "낙양", 63, 71, 23, 0, 168, 210, "출세", "-"); $gencount++;
75, "유봉",1280, 0, "낙양", 60, 65, 62, 0, 188, 220, "출세", "-"); $gencount++;
75, "유비",1281, 0, "낙양", 85, 75, 70, 0, 161, 223, "왕좌", "인덕"); $gencount++;
75, "유선1",1282, 0, "낙양", 24, 17, 21, 0, 207, 271, "대의", "-"); $gencount++;
55, "유순",1283, 0, "낙양", 67, 61, 54, 0, 184, 239, "출세", "-"); $gencount++;
75, "유심",1284, 0, "낙양", 63, 46, 70, 0, 238, 263, "왕좌", "-"); $gencount++;
129, "유약",1285, 0, "낙양", 67, 63, 61, 0, 206, 260, "유지", "-"); $gencount++;
55, "유언",1286, 0, "낙양", 60, 40, 74, 0, 132, 194, "할거", "-"); $gencount++;
27, "유엽",1287, 0, "낙양", 40, 29, 79, 0, 176, 235, "유지", "-"); $gencount++;
11, "유요",1288, 0, "낙양", 23, 22, 48, 0, 156, 195, "안전", "발명"); $gencount++;
96, "유우",1289, 0, "낙양", 68, 34, 72, 0, 145, 193, "왕좌", "-"); $gencount++;
55, "유장",1290, 0, "낙양", 38, 31, 63, 0, 162, 219, "할거", "수비"); $gencount++;
45, "유종",1291, 0, "낙양", 22, 26, 61, 0, 191, 208, "할거", "-"); $gencount++;
56, "유파",1292, 0, "낙양", 47, 32, 70, 0, 186, 222, "대의", "-"); $gencount++;
45, "유표1",1293, 0, "낙양", 71, 57, 71, 0, 142, 208, "할거", "-"); $gencount++;
27, "유표2",1294, 0, "낙양", 76, 55, 71, 0, 173, 229, "안전", "-"); $gencount++;
134, "유현",1295, 0, "낙양", 32, 56, 55, 0, 188, 252, "안전", "-"); $gencount++;
122, "육개",1296, 0, "낙양", 66, 30, 72, 0, 198, 269, "재간", "-"); $gencount++;
122, "육손",1297, 0, "낙양", 98, 68, 98, 0, 183, 245, "왕좌", "귀병"); $gencount++;
121, "육적",1298, 0, "낙양", 44, 29, 73, 0, 187, 219, "안전", "-"); $gencount++;
122, "육항",1299, 0, "낙양", 95, 69, 94, 0, 226, 274, "왕좌", "-"); $gencount++;
38, "윤대목",1300, 0, "낙양", 62, 49, 69, 0, 211, 270, "재간", "-"); $gencount++;
80, "윤묵",1301, 0, "낙양", 19, 28, 73, 0, 183, 239, "대의", "-"); $gencount++;
72, "윤상",1302, 0, "낙양", 30, 32, 42, 0, 194, 260, "대의", "-"); $gencount++;
136, "윤직",1303, 0, "낙양", 44, 58, 63, 0, 197, 237, "재간", "-"); $gencount++;
2, "이각",1304, 0, "낙양", 56, 77, 43, 0, 148, 198, "패권", "-"); $gencount++;
146, "이숙",1305, 0, "낙양", 27, 45, 67, 0, 156, 192, "재간", "-"); $gencount++;
71, "이엄",1306, 0, "낙양", 80, 84, 81, 0, 172, 234, "패권", "-"); $gencount++;
2, "이유",1307, 0, "낙양", 64, 22, 90, 0, 150, 192, "패권", "귀모"); $gencount++;
132, "이이",1308, 0, "낙양", 55, 75, 20, 0, 187, 222, "정복", "-"); $gencount++;
77, "이적",1309, 0, "낙양", 55, 27, 77, 0, 162, 226, "할거", "-"); $gencount++;
22, "이전",1310, 0, "낙양", 75, 68, 82, 0, 174, 216, "왕좌", "-"); $gencount++;
71, "이풍1",1311, 0, "낙양", 59, 56, 62, 0, 206, 260, "재간", "-"); $gencount++;
66, "이회",1312, 0, "낙양", 67, 50, 79, 0, 175, 231, "유지", "-"); $gencount++;
114, "잠혼",1313, 0, "낙양", 15, 16, 44, 0, 239, 280, "할거", "-"); $gencount++;
7, "장각",1314, 0, "낙양", 93, 25, 93, 0, 140, 185, "패권", "환술"); $gencount++;
34, "장간",1315, 0, "낙양", 19, 20, 70, 0, 175, 239, "재간", "-"); $gencount++;
7, "장개",1316, 0, "낙양", 48, 69, 19, 0, 155, 202, "안전", "-"); $gencount++;
122, "장굉",1317, 0, "낙양", 25, 21, 85, 0, 153, 212, "왕좌", "-"); $gencount++;
7, "장량",1318, 0, "낙양", 68, 81, 68, 0, 153, 185, "정복", "환술"); $gencount++;
15, "장로",1319, 0, "낙양", 76, 44, 80, 0, 163, 237, "유지", "축성"); $gencount++;
23, "장료",1320, 0, "낙양", 89, 93, 83, 0, 169, 222, "의협", "견고"); $gencount++;
7, "장보",1321, 0, "낙양", 78, 81, 76, 0, 148, 185, "패권", "환술"); $gencount++;
76, "장비",1322, 0, "낙양", 79, 99, 48, 0, 167, 221, "의협", "무쌍"); $gencount++;
62, "장서",1323, 0, "낙양", 44, 48, 35, 0, 225, 290, "출세", "-"); $gencount++;
120, "장소1",1324, 0, "낙양", 42, 24, 91, 0, 156, 236, "안전", "-"); $gencount++;
78, "장소2",1325, 0, "낙양", 51, 44, 71, 0, 202, 264, "재간", "-"); $gencount++;
72, "장송",1326, 0, "낙양", 49, 28, 93, 0, 170, 212, "할거", "통찰"); $gencount++;
148, "장수",1327, 0, "낙양", 71, 72, 69, 0, 154, 207, "할거", "-"); $gencount++;
145, "장양1",1328, 0, "낙양", 62, 66, 65, 0, 150, 199, "출세", "-"); $gencount++;
8, "장연",1329, 0, "낙양", 78, 66, 47, 0, 153, 210, "안전", "-"); $gencount++;
11, "장영",1330, 0, "낙양", 55, 65, 40, 0, 154, 195, "재간", "-"); $gencount++;
118, "장온",1331, 0, "낙양", 21, 30, 69, 0, 193, 231, "할거", "-"); $gencount++;
78, "장완",1332, 0, "낙양", 70, 55, 86, 0, 188, 246, "할거", "상재"); $gencount++;
15, "장위",1333, 0, "낙양", 65, 70, 29, 0, 172, 215, "대의", "-"); $gencount++;
36, "장윤",1334, 0, "낙양", 67, 59, 60, 0, 163, 208, "정복", "-"); $gencount++;
104, "장의거",1335, 0, "낙양", 68, 59, 34, 0, 159, 205, "대의", "-"); $gencount++;
68, "장익",1336, 0, "낙양", 75, 68, 63, 0, 188, 264, "유지", "-"); $gencount++;
56, "장임",1337, 0, "낙양", 83, 82, 74, 0, 169, 214, "대의", "견고"); $gencount++;
148, "장제1",1338, 0, "낙양", 70, 65, 59, 0, 144, 196, "할거", "-"); $gencount++;
32, "장제2",1339, 0, "낙양", 30, 33, 84, 0, 188, 249, "유지", "-"); $gencount++;
126, "장제3",1340, 0, "낙양", 74, 49, 61, 0, 236, 280, "할거", "-"); $gencount++;
17, "장패",1341, 0, "낙양", 44, 78, 43, 0, 165, 231, "할거", "-"); $gencount++;
76, "장포1",1342, 0, "낙양", 69, 85, 49, 0, 198, 229, "재간", "징병"); $gencount++;
113, "장포2",1343, 0, "낙양", 63, 66, 51, 0, 225, 264, "유지", "-"); $gencount++;
27, "장합",1344, 0, "낙양", 83, 91, 63, 0, 167, 231, "출세", "궁병"); $gencount++;
23, "장호",1345, 0, "낙양", 56, 62, 54, 0, 195, 240, "정복", "-"); $gencount++;
31, "장화",1346, 0, "낙양", 49, 24, 86, 0, 232, 300, "유지", "-"); $gencount++;
48, "장횡",1347, 0, "낙양", 53, 67, 25, 0, 178, 211, "재간", "-"); $gencount++;
141, "장훈",1348, 0, "낙양", 67, 61, 60, 0, 156, 206, "안전", "-"); $gencount++;
120, "장휴",1349, 0, "낙양", 42, 35, 70, 0, 204, 244, "재간", "-"); $gencount++;
126, "장흠",1350, 0, "낙양", 64, 66, 67, 0, 168, 219, "대의", "저격"); $gencount++;
96, "저수",1351, 0, "낙양", 82, 54, 88, 0, 156, 201, "할거", "반계"); $gencount++;
130, "전단",1352, 0, "낙양", 64, 73, 61, 0, 204, 261, "출세", "-"); $gencount++;
42, "전속",1353, 0, "낙양", 66, 57, 49, 0, 218, 272, "안전", "-"); $gencount++;
26, "전위1",1354, 0, "낙양", 61, 96, 34, 0, 160, 197, "의협", "필살"); $gencount++;
130, "전위2",1355, 0, "낙양", 74, 69, 62, 0, 230, 274, "출세", "-"); $gencount++;
128, "전종",1356, 0, "낙양", 79, 77, 74, 0, 183, 249, "패권", "-"); $gencount++;
42, "전주",1357, 0, "낙양", 69, 67, 51, 0, 169, 214, "의협", "-"); $gencount++;
96, "전풍",1358, 0, "낙양", 81, 41, 96, 0, 162, 200, "왕좌", "-"); $gencount++;
24, "정무",1359, 0, "낙양", 54, 38, 74, 0, 201, 265, "출세", "-"); $gencount++;
119, "정병",1360, 0, "낙양", 22, 25, 67, 0, 172, 226, "유지", "-"); $gencount++;
126, "정보",1361, 0, "낙양", 81, 64, 76, 0, 151, 216, "패권", "-"); $gencount++;
123, "정봉1",1362, 0, "낙양", 70, 77, 64, 0, 190, 271, "패권", "-"); $gencount++;
24, "정욱",1363, 0, "낙양", 80, 39, 90, 0, 141, 220, "패권", "신중"); $gencount++;
88, "정원",1364, 0, "낙양", 64, 77, 58, 0, 137, 190, "왕좌", "기병"); $gencount++;
7, "정원지",1365, 0, "낙양", 41, 74, 38, 0, 145, 185, "출세", "-"); $gencount++;
69, "정은",1366, 0, "낙양", 53, 62, 26, 0, 169, 211, "재간", "-"); $gencount++;
121, "제갈각",1367, 0, "낙양", 61, 53, 92, 0, 203, 253, "왕좌", "-"); $gencount++;
76, "제갈균",1368, 0, "낙양", 59, 45, 74, 0, 185, 252, "안전", "상재"); $gencount++;
121, "제갈근",1369, 0, "낙양", 60, 42, 88, 0, 174, 241, "왕좌", "경작"); $gencount++;
76, "제갈량",1370, 0, "낙양", 97, 55,100, 0, 181, 234, "왕좌", "집중"); $gencount++;
76, "제갈상",1371, 0, "낙양", 52, 75, 71, 0, 246, 263, "대의", "-"); $gencount++;
135, "제갈정",1372, 0, "낙양", 56, 57, 54, 0, 241, 300, "안전", "-"); $gencount++;
76, "제갈첨",1373, 0, "낙양", 73, 52, 76, 0, 227, 263, "대의", "-"); $gencount++;
135, "제갈탄",1374, 0, "낙양", 79, 79, 73, 0, 206, 258, "패권", "-"); $gencount++;
76, "조광",1375, 0, "낙양", 65, 67, 54, 0, 210, 263, "재간", "-"); $gencount++;
74, "조루",1376, 0, "낙양", 49, 37, 60, 0, 183, 219, "대의", "-"); $gencount++;
24, "조모",1377, 0, "낙양", 53, 32, 30, 0, 241, 260, "할거", "-"); $gencount++;
127, "조무",1378, 0, "낙양", 71, 68, 71, 0, 155, 191, "의협", "-"); $gencount++;
26, "조방",1379, 0, "낙양", 50, 20, 31, 0, 232, 274, "정복", "-"); $gencount++;
83, "조범",1380, 0, "낙양", 58, 40, 63, 0, 168, 218, "유지", "-"); $gencount++;
26, "조비",1381, 0, "낙양", 72, 69, 75, 0, 187, 226, "패권", "징병"); $gencount++;
19, "조상",1382, 0, "낙양", 68, 62, 31, 0, 207, 249, "패권", "-"); $gencount++;
147, "조성",1383, 0, "낙양", 44, 69, 51, 0, 163, 198, "안전", "-"); $gencount++;
26, "조순",1384, 0, "낙양", 66, 57, 72, 0, 170, 210, "정복", "-"); $gencount++;
25, "조식",1385, 0, "낙양", 19, 19, 90, 0, 192, 232, "왕좌", "귀모"); $gencount++;
25, "조앙",1386, 0, "낙양", 44, 65, 62, 0, 175, 197, "왕좌", "-"); $gencount++;
25, "조예",1387, 0, "낙양", 57, 55, 82, 0, 205, 239, "정복", "-"); $gencount++;
26, "조우",1388, 0, "낙양", 67, 55, 67, 0, 199, 260, "대의", "-"); $gencount++;
76, "조운",1389, 0, "낙양", 95, 98, 87, 0, 168, 229, "왕좌", "무쌍"); $gencount++;
25, "조웅",1390, 0, "낙양", 59, 27, 44, 0, 194, 220, "안전", "-"); $gencount++;
26, "조인",1391, 0, "낙양", 74, 79, 62, 0, 168, 223, "패권", "보병"); $gencount++;
25, "조조",1392, 0, "낙양",100, 80, 95, 0, 155, 220, "패권", "반계"); $gencount++;
26, "조진",1393, 0, "낙양", 82, 67, 65, 0, 185, 231, "정복", "-"); $gencount++;
25, "조창",1394, 0, "낙양", 75, 88, 37, 0, 190, 223, "정복", "돌격"); $gencount++;
76, "조통",1395, 0, "낙양", 65, 64, 55, 0, 209, 260, "재간", "-"); $gencount++;
84, "조표",1396, 0, "낙양", 34, 70, 16, 0, 151, 196, "안전", "-"); $gencount++;
7, "조홍1",1397, 0, "낙양", 52, 66, 42, 0, 156, 185, "유지", "-"); $gencount++;
24, "조홍2",1398, 0, "낙양", 72, 69, 44, 0, 169, 232, "패권", "-"); $gencount++;
26, "조환",1399, 0, "낙양", 34, 24, 42, 0, 246, 302, "정복", "-"); $gencount++;
19, "조훈",1400, 0, "낙양", 67, 63, 30, 0, 212, 249, "출세", "-"); $gencount++;
26, "조휴",1401, 0, "낙양", 75, 71, 70, 0, 174, 228, "패권", "-"); $gencount++;
19, "조희",1402, 0, "낙양", 64, 57, 71, 0, 210, 249, "대의", "-"); $gencount++;
22, "종요",1403, 0, "낙양", 16, 20, 74, 0, 151, 230, "유지", "-"); $gencount++;
20, "종회",1404, 0, "낙양", 84, 58, 93, 0, 225, 264, "패권", "-"); $gencount++;
128, "주거",1405, 0, "낙양", 73, 71, 72, 0, 190, 246, "유지", "-"); $gencount++;
118, "주방",1406, 0, "낙양", 56, 36, 76, 0, 200, 240, "할거", "-"); $gencount++;
126, "주연",1407, 0, "낙양", 73, 72, 51, 0, 182, 249, "할거", "-"); $gencount++;
126, "주유",1408, 0, "낙양", 97, 73, 97, 0, 175, 210, "패권", "신산"); $gencount++;
128, "주이",1409, 0, "낙양", 61, 55, 61, 0, 201, 257, "안전", "-"); $gencount++;
88, "주준",1410, 0, "낙양", 82, 75, 65, 0, 149, 195, "왕좌", "-"); $gencount++;
32, "주지",1411, 0, "낙양", 52, 77, 47, 0, 233, 295, "안전", "-"); $gencount++;
76, "주창",1412, 0, "낙양", 42, 79, 30, 0, 164, 219, "의협", "궁병"); $gencount++;
126, "주치",1413, 0, "낙양", 58, 55, 56, 0, 156, 224, "안전", "-"); $gencount++;
41, "주태1",1414, 0, "낙양", 62, 55, 61, 0, 207, 261, "안전", "-"); $gencount++;
126, "주태2",1415, 0, "낙양", 74, 88, 60, 0, 171, 225, "정복", "필살"); $gencount++;
128, "주환",1416, 0, "낙양", 84, 86, 74, 0, 177, 238, "정복", "-"); $gencount++;
29, "진건",1417, 0, "낙양", 62, 70, 62, 0, 214, 292, "정복", "-"); $gencount++;
29, "진교",1418, 0, "낙양", 21, 25, 67, 0, 175, 237, "유지", "-"); $gencount++;
28, "진군",1419, 0, "낙양", 60, 38, 87, 0, 167, 235, "대의", "-"); $gencount++;
143, "진궁",1420, 0, "낙양", 77, 51, 90, 0, 154, 198, "할거", "신중"); $gencount++;
79, "진규",1421, 0, "낙양", 22, 19, 71, 0, 132, 206, "할거", "-"); $gencount++;
72, "진도",1422, 0, "낙양", 71, 85, 70, 0, 171, 237, "대의", "-"); $gencount++;
79, "진등",1423, 0, "낙양", 64, 62, 71, 0, 169, 207, "할거", "-"); $gencount++;
37, "진림",1424, 0, "낙양", 50, 28, 82, 0, 160, 217, "재간", "-"); $gencount++;
124, "진무",1425, 0, "낙양", 62, 74, 59, 0, 176, 215, "재간", "-"); $gencount++;
66, "진복",1426, 0, "낙양", 36, 27, 76, 0, 160, 226, "재간", "-"); $gencount++;
50, "진수",1427, 0, "낙양", 25, 29, 83, 0, 233, 297, "대의", "-"); $gencount++;
81, "진식",1428, 0, "낙양", 47, 68, 52, 0, 191, 230, "출세", "-"); $gencount++;
79, "진진",1429, 0, "낙양", 58, 38, 64, 0, 170, 235, "재간", "-"); $gencount++;
28, "진태",1430, 0, "낙양", 79, 76, 70, 0, 210, 260, "대의", "-"); $gencount++;
11, "진횡",1431, 0, "낙양", 38, 58, 47, 0, 161, 195, "출세", "-"); $gencount++;
21, "차주",1432, 0, "낙양", 55, 66, 62, 0, 164, 199, "안전", "-"); $gencount++;
11, "착융",1433, 0, "낙양", 62, 59, 21, 0, 161, 194, "출세", "-"); $gencount++;
36, "채모",1434, 0, "낙양", 79, 69, 68, 0, 155, 208, "정복", "궁병"); $gencount++;
36, "채중",1435, 0, "낙양", 58, 43, 55, 0, 168, 208, "출세", "-"); $gencount++;
36, "채화",1436, 0, "낙양", 56, 47, 49, 0, 166, 208, "안전", "-"); $gencount++;
66, "초주",1437, 0, "낙양", 22, 26, 81, 0, 201, 270, "대의", "-"); $gencount++;
20, "최염",1438, 0, "낙양", 43, 54, 67, 0, 162, 216, "대의", "-"); $gencount++;
60, "축융",1439, 0, "낙양", 59, 87, 25, 0, 193, 246, "정복", "척사"); $gencount++;
60, "타사대왕",1440, 0, "낙양", 61, 72, 67, 0, 186, 225, "출세", "척사"); $gencount++;
124, "태사자",1441, 0, "낙양", 71, 97, 65, 0, 166, 209, "대의", "무쌍"); $gencount++;
124, "태사향",1442, 0, "낙양", 51, 69, 50, 0, 189, 246, "재간", "-"); $gencount++;
12, "포륭",1443, 0, "낙양", 53, 74, 20, 0, 174, 208, "안전", "-"); $gencount++;
74, "풍습",1444, 0, "낙양", 36, 64, 44, 0, 182, 222, "재간", "-"); $gencount++;
7, "하의",1445, 0, "낙양", 49, 68, 25, 0, 161, 195, "출세", "-"); $gencount++;
121, "하제",1446, 0, "낙양", 74, 73, 64, 0, 171, 227, "재간", "-"); $gencount++;
90, "하진",1447, 0, "낙양", 49, 69, 37, 0, 135, 189, "왕좌", "-"); $gencount++;
24, "하후덕",1448, 0, "낙양", 67, 64, 39, 0, 178, 218, "출세", "-"); $gencount++;
26, "하후돈",1449, 0, "낙양", 88, 92, 71, 0, 156, 220, "의협", "돌격"); $gencount++;
19, "하후무",1450, 0, "낙양", 38, 33, 37, 0, 201, 259, "안전", "-"); $gencount++;
24, "하후상",1451, 0, "낙양", 67, 62, 71, 0, 181, 225, "출세", "-"); $gencount++;
26, "하후연",1452, 0, "낙양", 79, 90, 58, 0, 162, 219, "패권", "궁병"); $gencount++;
26, "하후위",1453, 0, "낙양", 73, 76, 71, 0, 204, 254, "정복", "-"); $gencount++;
26, "하후은",1454, 0, "낙양", 49, 51, 39, 0, 180, 208, "안전", "-"); $gencount++;
23, "하후패",1455, 0, "낙양", 78, 88, 69, 0, 202, 262, "대의", "-"); $gencount++;
20, "하후현",1456, 0, "낙양", 57, 23, 75, 0, 208, 254, "유지", "-"); $gencount++;
26, "하후혜",1457, 0, "낙양", 76, 66, 78, 0, 206, 242, "정복", "-"); $gencount++;
26, "하후화",1458, 0, "낙양", 77, 61, 80, 0, 207, 265, "정복", "-"); $gencount++;
22, "학소",1459, 0, "낙양", 89, 81, 86, 0, 185, 229, "대의", "견고"); $gencount++;
126, "한당",1460, 0, "낙양", 68, 67, 64, 0, 156, 225, "할거", "-"); $gencount++;
93, "한복",1461, 0, "낙양", 66, 59, 42, 0, 149, 191, "안전", "-"); $gencount++;
8, "한섬",1462, 0, "낙양", 39, 62, 35, 0, 159, 196, "출세", "-"); $gencount++;
48, "한수",1463, 0, "낙양", 66, 76, 77, 0, 142, 215, "대의", "기병"); $gencount++;
40, "한숭",1464, 0, "낙양", 21, 25, 70, 0, 154, 210, "재간", "-"); $gencount++;
7, "한충",1465, 0, "낙양", 41, 66, 29, 0, 151, 185, "안전", "-"); $gencount++;
9, "한현",1466, 0, "낙양", 43, 61, 20, 0, 163, 208, "유지", "-"); $gencount++;
27, "한호",1467, 0, "낙양", 60, 73, 45, 0, 164, 218, "유지", "-"); $gencount++;
79, "향랑",1468, 0, "낙양", 51, 21, 77, 0, 167, 247, "대의", "-"); $gencount++;
79, "향총",1469, 0, "낙양", 76, 42, 73, 0, 195, 240, "왕좌", "-"); $gencount++;
139, "허공",1470, 0, "낙양", 65, 63, 59, 0, 155, 200, "유지", "-"); $gencount++;
21, "허유",1471, 0, "낙양", 47, 47, 57, 0, 155, 204, "재간", "-"); $gencount++;
23, "허의",1472, 0, "낙양", 31, 74, 47, 0, 213, 263, "출세", "-"); $gencount++;
26, "허저",1473, 0, "낙양", 57, 98, 27, 0, 169, 226, "정복", "무쌍"); $gencount++;
87, "허정",1474, 0, "낙양", 18, 29, 74, 0, 152, 222, "재간", "-"); $gencount++;
12, "형도영",1475, 0, "낙양", 49, 78, 23, 0, 174, 208, "출세", "-"); $gencount++;
148, "호거아",1476, 0, "낙양", 35, 76, 61, 0, 164, 206, "안전", "-"); $gencount++;
76, "호반",1477, 0, "낙양", 61, 58, 46, 0, 179, 233, "재간", "-"); $gencount++;
20, "호분",1478, 0, "낙양", 71, 60, 61, 0, 222, 288, "할거", "-"); $gencount++;
27, "호주천",1479, 0, "낙양", 77, 75, 65, 0, 169, 230, "정복", "-"); $gencount++;
20, "호준",1480, 0, "낙양", 67, 60, 46, 0, 200, 256, "재간", "-"); $gencount++;
2, "화웅",1481, 0, "낙양", 68, 88, 24, 0, 155, 191, "출세", "돌격"); $gencount++;
131, "화핵",1482, 0, "낙양", 37, 27, 75, 0, 217, 278, "안전", "-"); $gencount++;
10, "화흠",1483, 0, "낙양", 18, 43, 75, 0, 157, 231, "출세", "-"); $gencount++;
21, "환범",1484, 0, "낙양", 20, 25, 81, 0, 199, 249, "유지", "-"); $gencount++;
127, "황개",1485, 0, "낙양", 78, 85, 69, 0, 154, 218, "왕좌", "징병"); $gencount++;
56, "황권",1486, 0, "낙양", 76, 46, 77, 0, 167, 240, "대의", "-"); $gencount++;
41, "황란",1487, 0, "낙양", 29, 70, 25, 0, 200, 264, "재간", "-"); $gencount++;
88, "황보숭",1488, 0, "낙양", 83, 63, 73, 0, 132, 195, "왕좌", "-"); $gencount++;
72, "황충",1489, 0, "낙양", 84, 94, 67, 0, 148, 222, "왕좌", "궁병"); $gencount++;
50, "황호",1490, 0, "낙양", 15, 17, 48, 0, 226, 263, "안전", "-"); $gencount++;
147, "후성",1491, 0, "낙양", 56, 62, 33, 0, 158, 199, "정복", "-"); $gencount++;
123, "가화",1492, 0, "낙양", 50, 66, 40, 0, 176, 224, "-", "-"); $gencount++;
999, "건석",1493, 0, "낙양", 21, 12, 61, 0, 155, 189, "-", "-"); $gencount++;
999, "견씨",1494, 0, "낙양", 35, 24, 58, 0, 182, 221, "-", "-"); $gencount++;
40, "견홍",1495, 0, "낙양", 76, 72, 66, 0, 224, 272, "-", "-"); $gencount++;
120, "고담",1496, 0, "낙양", 33, 21, 69, 0, 203, 244, "-", "-"); $gencount++;
101, "고유",1497, 0, "낙양", 56, 44, 73, 0, 174, 263, "-", "-"); $gencount++;
132, "곽마",1498, 0, "낙양", 68, 71, 49, 0, 239, 280, "-", "-"); $gencount++;
39, "관구수",1499, 0, "낙양", 58, 63, 35, 0, 206, 265, "-", "-"); $gencount++;
39, "관구전",1500, 0, "낙양", 63, 58, 68, 0, 224, 255, "-", "-"); $gencount++;
999, "관로",1501, 0, "낙양", 62, 21, 75, 0, 191, 256, "-", "-"); $gencount++;
65, "관정",1502, 0, "낙양", 35, 50, 73, 0, 158, 199, "-", "-"); $gencount++;
137, "교수",1503, 0, "낙양", 67, 69, 39, 0, 143, 195, "-", "-"); $gencount++;
33, "구건",1504, 0, "낙양", 43, 56, 69, 0, 239, 272, "-", "-"); $gencount++;
41, "구본",1505, 0, "낙양", 52, 41, 70, 0, 232, 269, "-", "-"); $gencount++;
12, "구성",1506, 0, "낙양", 56, 71, 31, 0, 157, 187, "-", "-"); $gencount++;
21, "국연",1507, 0, "낙양", 52, 21, 71, 0, 160, 219, "-", "-"); $gencount++;
99, "국의",1508, 0, "낙양", 83, 79, 50, 0, 146, 191, "-", "-"); $gencount++;
34, "금의",1509, 0, "낙양", 18, 40, 63, 0, 177, 218, "-", "-"); $gencount++;
76, "나헌",1510, 0, "낙양", 86, 67, 75, 0, 218, 270, "-", "-"); $gencount++;
999, "남두",1511, 0, "낙양", 35, 25, 54, 0, 130, 200, "-", "-"); $gencount++;
54, "냉포",1512, 0, "낙양", 70, 82, 69, 0, 176, 214, "-", "-"); $gencount++;
124, "노숙2",1513, 0, "낙양", 70, 55, 76, 0, 208, 274, "-", "-"); $gencount++;
42, "누규",1514, 0, "낙양", 54, 19, 88, 0, 143, 212, "-", "-"); $gencount++;
6, "누반",1515, 0, "낙양", 65, 76, 39, 0, 178, 207, "-", "-"); $gencount++;
130, "누현",1516, 0, "낙양", 23, 20, 68, 0, 223, 275, "-", "-"); $gencount++;
40, "당균",1517, 0, "낙양", 33, 19, 81, 0, 229, 264, "-", "-"); $gencount++;
32, "당빈",1518, 0, "낙양", 70, 74, 62, 0, 235, 294, "-", "-"); $gencount++;
999, "대교",1519, 0, "낙양", 42, 10, 54, 0, 177, 235, "-", "-"); $gencount++;
28, "대릉",1520, 0, "낙양", 64, 75, 45, 0, 199, 258, "-", "-"); $gencount++;
129, "동조",1521, 0, "낙양", 16, 15, 51, 0, 221, 281, "-", "-"); $gencount++;
114, "등수",1522, 0, "낙양", 35, 20, 44, 0, 228, 288, "-", "-"); $gencount++;
50, "마막",1523, 0, "낙양", 22, 17, 5, 0, 221, 265, "-", "-"); $gencount++;
116, "만욱",1524, 0, "낙양", 20, 18, 66, 0, 240, 272, "-", "-"); $gencount++;
120, "맹종",1525, 0, "낙양", 48, 48, 67, 0, 216, 271, "-", "-"); $gencount++;
38, "문호",1526, 0, "낙양", 65, 74, 45, 0, 227, 279, "-", "-"); $gencount++;
999, "미씨",1527, 0, "낙양", 59, 15, 68, 0, 176, 208, "-", "-"); $gencount++;
39, "반림",1528, 0, "낙양", 66, 79, 8, 0, 168, 225, "-", "-"); $gencount++;
129, "반장",1529, 0, "낙양", 77, 78, 69, 0, 177, 222, "-", "-"); $gencount++;
94, "방열",1530, 0, "낙양", 58, 82, 28, 0, 153, 190, "-", "-"); $gencount++;
55, "방희",1531, 0, "낙양", 59, 38, 69, 0, 153, 218, "-", "-"); $gencount++;
30, "배수",1532, 0, "낙양", 10, 11, 77, 0, 223, 271, "-", "-"); $gencount++;
8, "번능",1533, 0, "낙양", 70, 61, 47, 0, 158, 194, "-", "-"); $gencount++;
999, "번씨",1534, 0, "낙양", 32, 17, 45, 0, 176, 220, "-", "-"); $gencount++;
49, "보도근",1535, 0, "낙양", 64, 73, 50, 0, 170, 233, "-", "-"); $gencount++;
129, "보천",1536, 0, "낙양", 68, 60, 72, 0, 222, 272, "-", "-"); $gencount++;
121, "보협",1537, 0, "낙양", 73, 53, 75, 0, 216, 264, "-", "-"); $gencount++;
28, "부하",1538, 0, "낙양", 44, 36, 85, 0, 209, 255, "-", "-"); $gencount++;
26, "비요",1539, 0, "낙양", 70, 65, 73, 0, 192, 228, "-", "-"); $gencount++;
31, "사마주",1540, 0, "낙양", 63, 53, 62, 0, 227, 283, "-", "-"); $gencount++;
41, "사찬",1541, 0, "낙양", 61, 71, 54, 0, 215, 264, "-", "-"); $gencount++;
128, "설후",1542, 0, "낙양", 16, 14, 71, 0, 221, 271, "-", "-"); $gencount++;
36, "성공영",1543, 0, "낙양", 73, 58, 80, 0, 172, 220, "-", "-"); $gencount++;
126, "성만",1544, 0, "낙양", 61, 69, 66, 0, 225, 276, "-", "-"); $gencount++;
999, "소교",1545, 0, "낙양", 57, 23, 66, 0, 178, 218, "-", "-"); $gencount++;
46, "소유",1546, 0, "낙양", 51, 61, 48, 0, 164, 210, "-", "-"); $gencount++;
31, "소제2",1547, 0, "낙양", 22, 16, 78, 0, 224, 268, "-", "-"); $gencount++;
126, "손교",1548, 0, "낙양", 77, 60, 69, 0, 181, 219, "-", "-"); $gencount++;
116, "손기",1549, 0, "낙양", 62, 65, 52, 0, 227, 276, "-", "-"); $gencount++;
999, "손상향",1550, 0, "낙양", 72, 62, 42, 0, 193, 244, "-", "-"); $gencount++;
125, "손익",1551, 0, "낙양", 69, 75, 26, 0, 184, 204, "-", "-"); $gencount++;
125, "손진",1552, 0, "낙양", 64, 71, 48, 0, 234, 280, "-", "-"); $gencount++;
123, "송겸",1553, 0, "낙양", 61, 48, 44, 0, 175, 215, "-", "-"); $gencount++;
85, "순심",1554, 0, "낙양", 20, 21, 79, 0, 164, 208, "-", "-"); $gencount++;
31, "순욱2",1555, 0, "낙양", 10, 16, 77, 0, 225, 289, "-", "-"); $gencount++;
31, "순의",1556, 0, "낙양", 16, 11, 73, 0, 207, 281, "-", "-"); $gencount++;
129, "시삭",1557, 0, "낙양", 36, 66, 44, 0, 226, 268, "-", "-"); $gencount++;
29, "신창",1558, 0, "낙양", 51, 29, 46, 0, 210, 272, "-", "-"); $gencount++;
999, "악신",1559, 0, "낙양", 53, 12, 46, 0, 175, 228, "-", "-"); $gencount++;
138, "악취",1560, 0, "낙양", 56, 68, 58, 0, 157, 195, "-", "-"); $gencount++;
138, "양강",1561, 0, "낙양", 62, 70, 42, 0, 160, 199, "-", "-"); $gencount++;
21, "양부",1562, 0, "낙양", 68, 55, 85, 0, 178, 239, "-", "-"); $gencount++;
72, "양서",1563, 0, "낙양", 56, 62, 66, 0, 198, 260, "-", "-"); $gencount++;
34, "양습",1564, 0, "낙양", 67, 49, 73, 0, 168, 230, "-", "-"); $gencount++;
16, "양앙",1565, 0, "낙양", 65, 70, 39, 0, 172, 215, "-", "-"); $gencount++;
17, "양임",1566, 0, "낙양", 71, 78, 56, 0, 170, 215, "-", "-"); $gencount++;
32, "양제",1567, 0, "낙양", 69, 63, 71, 0, 226, 291, "-", "-"); $gencount++;
33, "양조2",1568, 0, "낙양", 65, 61, 67, 0, 223, 286, "-", "-"); $gencount++;
48, "양추2",1569, 0, "낙양", 66, 67, 61, 0, 172, 238, "-", "-"); $gencount++;
140, "양홍",1570, 0, "낙양", 19, 17, 76, 0, 152, 199, "-", "-"); $gencount++;
31, "양혼",1571, 0, "낙양", 60, 67, 63, 0, 220, 278, "-", "-"); $gencount++;
123, "여거",1572, 0, "낙양", 71, 58, 69, 0, 196, 256, "-", "-"); $gencount++;
130, "여대",1573, 0, "낙양", 83, 72, 70, 0, 161, 256, "-", "-"); $gencount++;
136, "염상",1574, 0, "낙양", 29, 27, 69, 0, 158, 199, "-", "-"); $gencount++;
36, "염행",1575, 0, "낙양", 70, 86, 38, 0, 159, 222, "-", "-"); $gencount++;
73, "영수",1576, 0, "낙양", 69, 70, 74, 0, 234, 264, "-", "-"); $gencount++;
39, "오거",1577, 0, "낙양", 49, 63, 32, 0, 151, 211, "-", "-"); $gencount++;
126, "오경",1578, 0, "낙양", 73, 60, 57, 0, 159, 203, "-", "-"); $gencount++;
999, "오국태",1579, 0, "낙양", 31, 11, 60, 0, 161, 222, "-", "-"); $gencount++;
126, "오찬",1580, 0, "낙양", 69, 41, 78, 0, 181, 245, "-", "-"); $gencount++;
23, "온회",1581, 0, "낙양", 42, 40, 78, 0, 178, 222, "-", "-"); $gencount++;
21, "왕기2",1582, 0, "낙양", 70, 66, 63, 0, 217, 281, "-", "-"); $gencount++;
32, "왕도",1583, 0, "낙양", 48, 44, 70, 0, 210, 269, "-", "-"); $gencount++;
123, "왕돈",1584, 0, "낙양", 60, 65, 41, 0, 198, 256, "-", "-"); $gencount++;
34, "왕릉",1585, 0, "낙양", 73, 60, 71, 0, 172, 251, "-", "-"); $gencount++;
63, "왕문",1586, 0, "낙양", 64, 67, 32, 0, 162, 205, "-", "-"); $gencount++;
32, "왕상",1587, 0, "낙양", 25, 19, 65, 0, 180, 268, "-", "-"); $gencount++;
34, "왕숙",1588, 0, "낙양", 35, 21, 80, 0, 195, 256, "-", "-"); $gencount++;
33, "왕업",1589, 0, "낙양", 32, 6, 46, 0, 220, 280, "-", "-"); $gencount++;
35, "왕충",1590, 0, "낙양", 42, 58, 21, 0, 152, 214, "-", "-"); $gencount++;
1, "우보",1591, 0, "낙양", 43, 63, 12, 0, 159, 192, "-", "-"); $gencount++;
122, "우사",1592, 0, "낙양", 70, 33, 79, 0, 217, 273, "-", "-"); $gencount++;
138, "원요",1593, 0, "낙양", 44, 42, 45, 0, 177, 206, "-", "-"); $gencount++;
95, "원유",1594, 0, "낙양", 57, 38, 73, 0, 150, 193, "-", "-"); $gencount++;
31, "위관",1595, 0, "낙양", 69, 45, 81, 0, 220, 291, "-", "-"); $gencount++;
129, "위막",1596, 0, "낙양", 58, 62, 60, 0, 221, 268, "-", "-"); $gencount++;
55, "유괴",1597, 0, "낙양", 75, 72, 66, 0, 165, 214, "-", "-"); $gencount++;
129, "유략",1598, 0, "낙양", 72, 68, 59, 0, 206, 260, "-", "-"); $gencount++;
45, "유반",1599, 0, "낙양", 74, 79, 48, 0, 168, 210, "-", "-"); $gencount++;
29, "유복",1600, 0, "낙양", 54, 50, 73, 0, 164, 208, "-", "-"); $gencount++;
78, "유선2",1601, 0, "낙양", 9, 21, 39, 0, 224, 264, "-", "-"); $gencount++;
139, "유섭",1602, 0, "낙양", 62, 79, 26, 0, 158, 190, "-", "-"); $gencount++;
28, "유소",1603, 0, "낙양", 66, 51, 73, 0, 195, 264, "-", "-"); $gencount++;
128, "유승",1604, 0, "낙양", 46, 69, 29, 0, 215, 258, "-", "-"); $gencount++;
129, "유찬",1605, 0, "낙양", 74, 75, 66, 0, 172, 255, "-", "-"); $gencount++;
129, "유평",1606, 0, "낙양", 65, 70, 67, 0, 218, 272, "-", "-"); $gencount++;
138, "유훈",1607, 0, "낙양", 51, 64, 50, 0, 163, 216, "-", "-"); $gencount++;
48, "이감",1608, 0, "낙양", 59, 67, 33, 0, 176, 211, "-", "-"); $gencount++;
19, "이승",1609, 0, "낙양", 13, 26, 32, 0, 201, 249, "-", "-"); $gencount++;
22, "이통",1610, 0, "낙양", 75, 84, 52, 0, 168, 211, "-", "-"); $gencount++;
138, "이풍2",1611, 0, "낙양", 72, 77, 50, 0, 158, 199, "-", "-"); $gencount++;
20, "이풍3",1612, 0, "낙양", 23, 25, 71, 0, 204, 254, "-", "-"); $gencount++;
29, "장구",1613, 0, "낙양", 69, 71, 47, 0, 201, 263, "-", "-"); $gencount++;
21, "장기",1614, 0, "낙양", 77, 35, 79, 0, 170, 223, "-", "-"); $gencount++;
74, "장남",1615, 0, "낙양", 71, 64, 38, 0, 187, 222, "-", "-"); $gencount++;
100, "장막",1616, 0, "낙양", 53, 52, 70, 0, 155, 195, "-", "-"); $gencount++;
7, "장만성",1617, 0, "낙양", 73, 83, 47, 0, 143, 184, "-", "-"); $gencount++;
135, "장반",1618, 0, "낙양", 56, 73, 66, 0, 227, 282, "-", "-"); $gencount++;
78, "장빈",1619, 0, "낙양", 30, 28, 67, 0, 216, 263, "-", "-"); $gencount++;
124, "장승",1620, 0, "낙양", 75, 68, 75, 0, 178, 244, "-", "-"); $gencount++;
999, "장양2",1621, 0, "낙양", 58, 50, 47, 0, 130, 184, "-", "-"); $gencount++;
68, "장억",1622, 0, "낙양", 82, 80, 54, 0, 190, 254, "-", "-"); $gencount++;
75, "장준",1623, 0, "낙양", 65, 67, 66, 0, 224, 263, "-", "-"); $gencount++;
20, "장집",1624, 0, "낙양", 31, 27, 74, 0, 196, 254, "-", "-"); $gencount++;
39, "장특",1625, 0, "낙양", 71, 53, 74, 0, 209, 265, "-", "-"); $gencount++;
96, "저곡",1626, 0, "낙양", 57, 53, 67, 0, 184, 204, "-", "-"); $gencount++;
128, "전기",1627, 0, "낙양", 51, 69, 55, 0, 231, 258, "-", "-"); $gencount++;
23, "전만",1628, 0, "낙양", 52, 74, 38, 0, 181, 235, "-", "-"); $gencount++;
128, "전상",1629, 0, "낙양", 5, 6, 11, 0, 208, 258, "-", "-"); $gencount++;
130, "전역",1630, 0, "낙양", 60, 62, 37, 0, 212, 265, "-", "-"); $gencount++;
75, "전예",1631, 0, "낙양", 80, 62, 83, 0, 171, 252, "-", "-"); $gencount++;
64, "전해",1632, 0, "낙양", 71, 63, 57, 0, 154, 199, "-", "-"); $gencount++;
123, "정봉2",1633, 0, "낙양", 67, 68, 52, 0, 198, 266, "-", "-"); $gencount++;
22, "정의",1634, 0, "낙양", 17, 3, 66, 0, 184, 220, "-", "-"); $gencount++;
81, "제갈교",1635, 0, "낙양", 55, 17, 77, 0, 204, 228, "-", "-"); $gencount++;
40, "제갈서",1636, 0, "낙양", 45, 43, 27, 0, 218, 286, "-", "-"); $gencount++;
25, "조충",1637, 0, "낙양", 14, 7, 80, 0, 196, 208, "-", "-"); $gencount++;
121, "종리목",1638, 0, "낙양", 84, 68, 75, 0, 214, 269, "-", "-"); $gencount++;
22, "종육",1639, 0, "낙양", 27, 11, 71, 0, 223, 263, "-", "-"); $gencount++;
122, "좌혁",1640, 0, "낙양", 60, 66, 51, 0, 232, 280, "-", "-"); $gencount++;
36, "주령",1641, 0, "낙양", 77, 70, 69, 0, 170, 236, "-", "-"); $gencount++;
115, "주앙",1642, 0, "낙양", 75, 64, 64, 0, 162, 195, "-", "-"); $gencount++;
52, "주포",1643, 0, "낙양", 59, 72, 12, 0, 191, 225, "-", "-"); $gencount++;
11, "주흔",1644, 0, "낙양", 67, 53, 77, 0, 159, 196, "-", "-"); $gencount++;
140, "진기",1645, 0, "낙양", 58, 67, 46, 0, 165, 198, "-", "-"); $gencount++;
142, "진란",1646, 0, "낙양", 65, 70, 43, 0, 157, 204, "-", "-"); $gencount++;
25, "진랑",1647, 0, "낙양", 57, 70, 38, 0, 192, 234, "-", "-"); $gencount++;
12, "진응",1648, 0, "낙양", 62, 69, 49, 0, 172, 208, "-", "-"); $gencount++;
124, "진표",1649, 0, "낙양", 62, 49, 74, 0, 204, 237, "-", "-"); $gencount++;
999, "채염",1650, 0, "낙양", 40, 22, 64, 0, 168, 237, "-", "-"); $gencount++;
999, "초선",1651, 0, "낙양", 66, 15, 72, 0, 176, 211, "-", "-"); $gencount++;
135, "초이",1652, 0, "낙양", 54, 65, 55, 0, 219, 266, "-", "-"); $gencount++;
65, "추단",1653, 0, "낙양", 63, 71, 36, 0, 148, 193, "-", "-"); $gencount++;
999, "추씨",1654, 0, "낙양", 36, 13, 54, 0, 165, 225, "-", "-"); $gencount++;
71, "추정",1655, 0, "낙양", 67, 65, 66, 0, 144, 193, "-", "-"); $gencount++;
145, "파재",1656, 0, "낙양", 69, 75, 52, 0, 145, 184, "-", "-"); $gencount++;
22, "포신",1657, 0, "낙양", 78, 60, 83, 0, 152, 192, "-", "-"); $gencount++;
114, "하식",1658, 0, "낙양", 18, 38, 29, 0, 230, 284, "-", "-"); $gencount++;
36, "하안",1659, 0, "낙양", 6, 27, 72, 0, 190, 249, "-", "-"); $gencount++;
999, "하후씨",1660, 0, "낙양", 29, 16, 47, 0, 186, 249, "-", "-"); $gencount++;
5, "학맹",1661, 0, "낙양", 57, 66, 41, 0, 156, 197, "-", "-"); $gencount++;
98, "한거자",1662, 0, "낙양", 53, 59, 30, 0, 158, 200, "-", "-"); $gencount++;
19, "한덕",1663, 0, "낙양", 62, 79, 24, 0, 171, 228, "-", "-"); $gencount++;
140, "한윤",1664, 0, "낙양", 27, 24, 68, 0, 155, 197, "-", "-"); $gencount++;
999, "허소",1665, 0, "낙양", 53, 27, 60, 0, 150, 195, "-", "-"); $gencount++;
30, "호열",1666, 0, "낙양", 77, 69, 76, 0, 225, 272, "-", "-"); $gencount++;
76, "호제",1667, 0, "낙양", 58, 42, 68, 0, 207, 264, "-", "-"); $gencount++;
149, "호진",1668, 0, "낙양", 65, 77, 13, 0, 146, 190, "-", "-"); $gencount++;
29, "호질",1669, 0, "낙양", 73, 50, 75, 0, 192, 250, "-", "-"); $gencount++;
7, "환계",1670, 0, "낙양", 12, 25, 67, 0, 156, 221, "-", "-"); $gencount++;
56, "황숭",1671, 0, "낙양", 68, 64, 74, 0, 208, 263, "-", "-"); $gencount++;
999, "황승언",1672, 0, "낙양", 68, 17, 81, 0, 165, 222, "-", "-"); $gencount++;
999, "황월영",1673, 0, "낙양", 58, 14, 75, 0, 186, 235, "-", "-"); $gencount++;
45, "황조",1674, 0, "낙양", 74, 65, 57, 0, 148, 208, "-", "-"); $gencount++;
48, "후선",1675, 0, "낙양", 56, 66, 35, 0, 175, 228, "-", "-"); $gencount++;
8, "휴고",1676, 0, "낙양", 61, 72, 40, 0, 151, 199, "-", "-"); $gencount++;
98, "휴원진",1677, 0, "낙양", 53, 63, 38, 0, 155, 200, "-", "-"); $gencount++;
22, "희지재",1678, 0, "낙양", 24, 5, 86, 0, 157, 194, "-", "-"); $gencount++;
+23 -377
View File
@@ -4,396 +4,42 @@ namespace sammo;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
Session::requireLogin()->loginGame()->setReadOnly();
$session = Session::requireLogin()->loginGame()->setReadOnly(); $mapName = GameConst::$mapName;
$userID = Session::getUserID();
increaseRefresh("메인", 1);
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
if (!$userID) {
header('Location:..');
die();
}
//턴 실행.
TurnExecutionHelper::executeAllCommand();
if (!$session->isGameLoggedIn()) {
header('Location:..');
die();
}
$me = $db->queryFirstRow(
'SELECT no,con,turntime,newmsg,newvote,`officer_level` from general where owner = %i',
$userID
);
//그새 사망이면
if ($me === null) {
$session->logoutGame();
header('Location: ../');
die();
}
$gameStor->cacheAll(true);
if ($me['newmsg'] == 1 || $me['newvote'] == 1) {
$db->update('general', [
'newmsg' => 0,
'newvote' => 0
], 'owner=%i', $userID);
}
$plock = $db->queryFirstField('SELECT plock FROM plock LIMIT 1');
$con = checkLimit($me['con']);
if ($con >= 2) {
printLimitMsg($me['turntime']);
exit();
}
$generalObj = General::createGeneralObjFromDB($me['no']);
$generalObj->setRawCity($db->queryFirstRow('SELECT * FROM city WHERE city = %i', $generalObj->getCityID()));
$scenario = $gameStor->scenario_text;
$nationID = $generalObj->getNationID();
if ($nationID) {
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
$nationStor->cacheAll();
}
if ($gameStor->extended_general == 0) {
$extend = "표준";
} else {
$extend = "확장";
}
if ($gameStor->fiction == 0) {
$fiction = "사실";
} else {
$fiction = "가상";
}
if ($gameStor->npcmode == 0) {
$npcmode = "불가능";
} else if ($gameStor->npcmode == 1) {
$npcmode = "가능";
} else {
$npcmode = "선택 생성";
}
$color = "cyan";
$mapTheme = $gameStor->map_theme;
$serverName = UniqueConst::$serverName;
$serverCnt = $gameStor->server_cnt;
$auctionCount = $db->queryFirstField('SELECT count(`no`) FROM auction');
$myNationStatic = getNationStaticInfo($generalObj->getNationID());
$nationColorType = substr($myNationStatic['color'] ?? '#000000', 1);
$autorunUser = ($gameStor->autorun_user) ?? [];
$otherTextInfo = [];
if ($gameStor->join_mode == 'onlyRandom') {
$otherTextInfo[] = '랜덤 임관 전용';
}
if ($autorunUser['limit_minutes'] ?? false) {
$otherTextInfo[] = getAutorunInfo($autorunUser);
}
if (!$otherTextInfo) {
$otherTextInfo = '표준';
} else {
$otherTextInfo = join(', ', $otherTextInfo);
}
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<title><?= $serverName ?>: 메인</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=500" /> <meta name="viewport" content="width=500" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <title><?= UniqueConst::$serverName ?>: 메인</title>
<?= WebUtil::printJS('d_shared/base_map.js') ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<?= WebUtil::printDist('vue', 'v_main', true) ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printCSS('css/map.css') ?>
<?= WebUtil::printStaticValues([ <?= WebUtil::printStaticValues([
'serverNick' => DB::prefix(), 'staticValues' => [
'serverID' => UniqueConst::$serverID, 'serverName' => UniqueConst::$serverName,
'maxTurn' => GameConst::$maxTurn, 'serverNick' => DB::prefix(),
'maxPushTurn' => 12, 'serverID' => UniqueConst::$serverID,
'commandList' => getCommandTable($generalObj), 'mapName' => GameConst::$mapName,
'serverNow' => TimeUtil::now(false), 'unitSet' => GameConst::$unitSet,
'baseColor2' => GameConst::$basecolor2,
]) ?> 'maxTurn' => GameConst::$maxTurn,
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.1/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous"> 'maxPushTurn' => 12,
'serverNow' => TimeUtil::now(false),
]
], false) ?>
<?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printJS("js/map/theme_{$mapName}.js") ?>
<?= WebUtil::printCSS('../d_shared/common.css') ?>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard/dist/web/static/pretendard.css" />
<?= WebUtil::printDist('vue', 'v_front', true) ?>
</head> </head>
<body class="img_back sam-color-<?= $nationColorType ?>"> <body>
<div id="container" class="bg0"> <div id="app"></div>
<div class="row toolbars gx-0">
<div class="buttonPlate"><?= allButton($gameStor->npcmode == 1) ?></button></div>
</div>
<div class="tb_layout row gx-0">
<div id="server_title" class="row py-2 center">
<h3>삼국지 모의전투 HiDCHe <?= $serverName . $serverCnt ?>기 <span class="avoid-wrap">(<font color=cyan><?= $scenario ?></font>)</span></h3>
</div>
<div class="row center gx-0">
<div class="s-border-t col py-2 col-8 col-md-4" style="color:<?= $color ?>;">
<?= $scenario ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC수 : <?= $extend ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC상성 : <?= $fiction ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
NPC선택 : <?= $npcmode ?>
</div>
<div class="s-border-t col py-2 col-4 col-md-2" style="color:<?= $color ?>;">
기타 설정: <?= $otherTextInfo ?>
</div>
<div class="s-border-t col py-2 col-8 col-md-4"><?= info(2) ?></div>
<div class="s-border-t col py-2 col-4 col-md-2">전체 접속자 수 : <?= $gameStor->online_user_cnt ?> 명</div>
<div class="s-border-t col py-2 col-4 col-md-2">턴당 갱신횟수 : <?= $gameStor->conlimit ?>회</div>
<div class="s-border-t col py-2 col-8 col-md-4"><?= info(3) ?></div>
<div class="s-border-t py-2 col col-6 col-md-4"><?php if ($gameStor->tournament == 0) : ?>
<span style='color:magenta'>현재 토너먼트 경기 없음</span>
<?php else : ?>
↑<span style='color:cyan'><?=
([
'전력전', '통솔전', '일기토', '설전',
])[$gameStor->tnmt_type] ?? '' ?> <?= getTournament($gameStor->tournament) ?> <?= getTournamentTime() ?></span>↑
<?php endif; ?>
</div>
<div class="s-border-t py-2 col col-6 col-md-2">
<div style="display:inline-block;"><?= !$plock ? ("<span style='color:cyan;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") : ("<span style='color:magenta;'>동작 시각: " . substr($gameStor->turntime, 5, 14) . "</span>") ?></div>
</div>
<div class="s-border-t py-2 col col-6 col-md-2">
<?php if ($auctionCount > 0) : ?>
<span style='color:cyan'><?= $auctionCount ?>건</span> 거래 진행중
<?php else : ?>
<span style='color:magenta'>진행중 거래 없음</span>
<?php endif; ?>
</div>
<div class="s-border-t py-2 col col-6 col-md-4 vote-cell">
<?php
$vote = $gameStor->vote ?: [''];
$vote_title = Tag2Code($gameStor->vote_title ?? '-');
?>
<?php if ($vote[0] == "") : ?>
<span style='color:magenta'>진행중 설문 없음</span>
<?php else : ?>
<span style='color:cyan'>설문 진행중</span> : <span><?= $vote_title ?></span>
<?php endif; ?>
</div>
</div>
<div class="row gx-0">
<div class="col s-border-t px-2 py-2">접속중인 국가: <?= $gameStor->online_nation ?></div>
</div>
<div class="row gx-0">
<div class="col s-border-t px-2 py-2">운영자 메세지 : <span style='color:yellow;'><?= $gameStor->msg ?></span></div>
</div>
<div class="row gx-0">
<div class="col s-border-t py-2" id="nation-msg-position">
<div class="px-2">【 국가방침 】</div>
<div id='nation-msg-box'>
<div id='nation-msg'><?= nationMsg($generalObj) ?></div>
</div>
</div>
</div>
<div class="row gx-0">
<div class="col s-border-t px-2 py-2">
【 접속자 】<?= onlinegen($generalObj) ?>
</div>
</div>
<?php if ($session->userGrade >= 5) : ?>
<div class="row">
<div class="col">
<a href='_admin1.php' target='_blank'><button type='button'>게임관리</button></a>
<a href='_admin2.php' target='_blank'><button type='button'>회원관리</button></a>
<a href='_admin4.php' target='_blank'><button type='button'>멀티관리</button></a>
<a href='_admin5.php' target='_blank'><button type='button'>일제정보</button></a>
<a href='_admin7.php' target='_blank'><button type='button'>로그정보</button></a>
<a href='_admin8.php' target='_blank'><button type='button'>외교정보</button></a>
<a href='_119.php' target='_blank'><button type='button'>119</button></a>
</div>
</div>
<?php elseif ($session->userGrade == 4) : ?>
<div class="row">
<div class="col">
<a href='_119.php' target='_blank'><button type='button'>119</button></a>
</div>
</div>
<?php endif; ?>
<div id="map_view" class="gx-0">
<div id="mapZone" class="view-item"><?= getMapHtml($mapTheme) ?></div>
<div class="view-item" id="reservedCommandZone">
<div id="reservedCommandList"></div>
<div id="actionMiniPlate" class="gx-0 row">
<div class="col">
<div class="gx-1 row">
<div class="col-8 d-grid"><button type='button' class='btn btn-sammo-base2 refreshPage'>갱 신</button></div>
<div class="col-4 d-grid"><button type='button' class='btn btn-sammo-base2' onclick="location.replace('../')">로비로</button></div>
</div>
</div>
</div>
</div>
<div id="cityInfo" class="view-item" style="border:none;text-align:center;"><?= cityInfo($generalObj) ?></div>
<div id="nation-position"><?php myNationInfo($generalObj); ?></div>
<div id="general-position"><?php generalInfo($generalObj); ?></div>
<div id="generalCommandButton" class="row gx-0">
<div class="buttonPlate bg2"><?= commandButton(['btnClass' => 'btn btn-sammo-nation']) ?></div>
</div>
</div>
</div>
<div id="actionMiniPlateSub" class="gx-0 row">
<div class="col">
<div class="gx-1 row">
<div class="col-3 d-grid"><button type='button' class="btn btn-dark" onclick="scrollHardTo('reservedCommandList')">명령으로</button></div>
<div class="col-5 d-grid"><button type='button' class='btn btn-sammo-base2 refreshPage'>갱 신</button></div>
<div class="col-4 d-grid"><button type='button' class='btn btn-sammo-base2' onclick="location.replace('../')">로비로</button></div>
</div>
</div>
</div>
<div class="row gx-0">
<div class="col-md-6" id="general_public_record-position">
<div class="bg1 center s-border-tb"><b>장수 동향</b></div>
<div id="general_public_record" style="text-align:left;"><?= formatHistoryToHTML(getGlobalActionLogRecent(15)) ?></div>
</div>
<div class="col-md-6" id="general_log-position">
<div class="bg1 center s-border-tb"><b>개인 기록</b></div>
<div id="general_log" style="text-align:left;"><?= formatHistoryToHTML(getGeneralActionLogRecent($me['no'], 15)) ?></div>
</div>
<div class="col-12" id="world_history-position">
<div class="bg1 center s-border-tb"><b>중원 정세</b></div>
<div id="world_history" colspan=2 style="text-align:left;"><?= formatHistoryToHTML(getGlobalHistoryLogRecent(15)) ?></div>
</div>
</div>
<div class="row toolbars gx-0">
<div class="buttonPlate"><?= allButton($gameStor->npcmode == 1) ?></div>
<div id="message_board" class="row gx-0">
<div class="message_input_form bg0 gx-0 row">
<div id="mailbox_list-col" class="col-6 col-md-2 d-grid">
<select id="mailbox_list" size="1" class="form-control bg-dark text-white">
</select>
</div>
<div id="msg_input-col" class="col-12 col-md-8 d-grid">
<input type="text" id="msg_input" maxlength="99" class="form-control">
</div>
<div id="msg_submit-col" class="col-6 col-md-2 d-grid"><button id="msg_submit" class="btn btn-primary">서신전달&amp;갱신</button></div>
</div>
<div class="col-md-6 board_side bg0"><a id="public_talk_position"></a>
<div class="board_header bg0">전체 메시지(최고99자)</div>
<section class="public_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="public">이전 메시지 불러오기</button></div>
</section>
</div>
<div class="col-md-6 board_side bg0"><a id="national_talk_position"></a>
<div class="board_header bg0">국가 메시지(최고99자)</div>
<section class="national_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="national">이전 메시지 불러오기</button></div>
</section>
</div>
<div class="col-md-6 board_side bg0"><a id="private_talk_position"></a>
<div class="board_header bg0">개인 메시지(최고99자)</div>
<section class="private_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="private">이전 메시지 불러오기</button></div>
</section>
</div>
<div class="col-md-6 board_side bg0"><a id="diplomacy_talk_position"></a>
<div class="board_header bg0">외교 메시지(최고99자)</div>
<section class="diplomacy_message">
<div class="d-grid"><button type="button" class="load_old_message btn btn-secondary" data-msg_type="diplomacy">이전 메시지 불러오기</button></div>
</section>
</div>
</div>
<div class="row toolbars gx-0">
<div class="buttonPlate"><?= allButton($gameStor->npcmode == 1) ?></div><?= banner() ?>
</div>
</div>
<?php
if ($con == 1) {
MessageBox("접속제한이 얼마 남지 않았습니다!");
}
if ($me['newmsg'] == 1) {
MessageBox("새로운 서신이 도착했습니다!");
}
if ($me['newvote'] == 1) {
$develcost = $gameStor->develcost * 5;
MessageBox("설문조사에 참여하시면 금{$develcost}과 유니크템을 드립니다! (우측 상단 설문조사 메뉴)");
}
?>
</div>
<nav class="navbar navbar-expand fixed-bottom navbar-dark bg-dark d-sm-block d-md-none p-0" id="navbar500">
<div class="container-fluid px-0">
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mx-auto">
<li class="nav-item dropup">
<div class="dropdown-toggle text-white btn btn-sammo-base2" id="navbarGlobal" role="button" data-bs-toggle="dropdown" aria-expanded="false">
외부 메뉴
</div>
<ul class="dropdown-menu dropdown-menu-start" aria-labelledby="navbarGlobal" id="navbarGlobalItems">
<?= allButton($gameStor->npcmode == 1, ['btnBegin' => '<li>', 'btnEnd' => '</li>', 'btnClass' => 'dropdown-item']) ?>
</ul>
</li>
<li class="nav-item dropup">
<div class="dropdown-toggle btn btn-sammo-nation" id="navbarNation" role="button" data-bs-toggle="dropdown" aria-expanded="false">
국가 메뉴
</div>
<ul class="dropdown-menu" aria-labelledby="navbarNation" id="navbarNationItems">
<?= commandButton(['btnBegin' => '<li>', 'btnEnd' => '</li>', 'btnClass' => 'dropdown-item']) ?>
</ul>
</li>
<li class="nav-item dropup">
<div class="dropdown-toggle text-white btn btn-dark" id="navbarQuick" role="button" data-bs-toggle="dropdown" aria-expanded="false">
빠른 이동
</div>
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="navbarDropdown" id="navbarQuickItems">
<li><a class="dropdown-item disabled">국가 정보</a></button></li>
<hr class="dropdown-divider">
</hr>
<li><button type="button" onclick="scrollHardTo('nation-msg-position')" class="dropdown-item">방침</button></li>
<li><button type="button" onclick="scrollHardTo('reservedCommandList')" class="dropdown-item">명령</button></li>
<li><button type="button" onclick="scrollHardTo('nation-position')" class="dropdown-item">국가</button></li>
<li><button type="button" onclick="scrollHardTo('general-position')" class="dropdown-item">장수</button></li>
<li><button type="button" onclick="scrollHardTo('cityInfo')" class="dropdown-item">도시</button></li>
<li><a class="dropdown-item disabled">동향 정보</a></button></li>
<hr class="dropdown-divider">
</hr>
<li><button type="button" onclick="scrollHardTo('mapZone')" class="dropdown-item">지도</button></li>
<li><button type="button" onclick="scrollHardTo('general_public_record-position')" class="dropdown-item">동향</button></li>
<li><button type="button" onclick="scrollHardTo('general_log-position')" class="dropdown-item">개인</button></li>
<li><button type="button" onclick="scrollHardTo('world_history-position')" class="dropdown-item">정세</button></li>
<li><span>&nbsp;</span></li>
<li><a class="dropdown-item disabled">메시지</a></button></li>
<hr class="dropdown-divider">
</hr>
<li><button type="button" onclick="scrollHardTo('public_talk_position')" class="dropdown-item">전체</button></li>
<li><button type="button" onclick="scrollHardTo('national_talk_position')" class="dropdown-item">국가</button></li>
<li><button type="button" onclick="scrollHardTo('private_talk_position')" class="dropdown-item">개인</button></li>
<li><button type="button" onclick="scrollHardTo('diplomacy_talk_position')" class="dropdown-item">외교</button></li>
<li><button type='button' class='btn btn-sammo-base2' onclick="location.replace('../')">로비로</button></li>
</ul>
</li>
<li class="nav-item">
<a class="refreshPage btn btn-sammo-base2 text-white" role="button">갱신</a>
</li>
</ul>
</div>
</div>
</nav>
</body> </body>
</html> </html>
+18 -21
View File
@@ -28,17 +28,19 @@ if ($session->userGrade < 5 && !$allowReset) {
<head> <head>
<title>설치</title> <title>설치</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
<?= WebUtil::printCSS('css/install.css') ?> <?= WebUtil::printCSS('css/install.css') ?>
<?= WebUtil::printDist('vue', [], true) ?>
<?= WebUtil::printDist('ts', ['common', 'install']) ?> <?= WebUtil::printDist('ts', ['common', 'install']) ?>
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1> <h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-lg-center">
<div class="col col-lg-8"> <div class="col col-lg-8">
<div class="card" id="game_form_card"> <div class="card" id="game_form_card">
@@ -92,8 +94,8 @@ if ($session->userGrade < 5 && !$allowReset) {
<label for="fiction" class="col-sm-3 col-form-label">NPC 상성</label> <label for="fiction" class="col-sm-3 col-form-label">NPC 상성</label>
<div class="col-sm-9"> <div class="col-sm-9">
<div id="fiction" class="btn-group btn-group-toggle" data-bs-toggle="buttons"> <div id="fiction" class="btn-group btn-group-toggle" data-bs-toggle="buttons">
<input type="radio" id="fiction_0" class="btn-check" name="fiction" value="0" checked><label for="fiction_0" class="btn btn-secondary"> 연의 </label> <input type="radio" id="fiction_0" class="btn-check" name="fiction" value="0"><label for="fiction_0" class="btn btn-secondary"> 연의 </label>
<input type="radio" id="fiction_1" class="btn-check" name="fiction" value="1"><label for="fiction_1" class="btn btn-secondary"> 가상 </label> <input type="radio" id="fiction_1" class="btn-check" name="fiction" value="1" checked><label for="fiction_1" class="btn btn-secondary"> 가상 </label>
</div> </div>
</div> </div>
</div> </div>
@@ -113,6 +115,7 @@ if ($session->userGrade < 5 && !$allowReset) {
<div class="col-sm-9"> <div class="col-sm-9">
<div id="block_general_create" class="btn-group btn-group-toggle" data-bs-toggle="buttons"> <div id="block_general_create" class="btn-group btn-group-toggle" data-bs-toggle="buttons">
<input type="radio" class="btn-check" id="block_general_create_0" name="block_general_create" value="0" checked><label for="block_general_create_0" class="btn btn-secondary">가능</label> <input type="radio" class="btn-check" id="block_general_create_0" name="block_general_create" value="0" checked><label for="block_general_create_0" class="btn btn-secondary">가능</label>
<input type="radio" class="btn-check" id="block_general_create_2" name="block_general_create" value="2"><label for="block_general_create_2" class="btn btn-secondary">장수명무작위</label>
<input type="radio" class="btn-check" id="block_general_create_1" name="block_general_create" value="1"><label for="block_general_create_1" class="btn btn-secondary">불가</label> <input type="radio" class="btn-check" id="block_general_create_1" name="block_general_create" value="1"><label for="block_general_create_1" class="btn btn-secondary">불가</label>
</div> </div>
</div> </div>
@@ -134,13 +137,13 @@ if ($session->userGrade < 5 && !$allowReset) {
<div class="col-sm-9"> <div class="col-sm-9">
<div class="input-group"> <div class="input-group">
<div class="btn-group btn-group-toggle" data-bs-toggle="buttons"> <div class="btn-group btn-group-toggle" data-bs-toggle="buttons">
<input type="checkbox" id="autorun_develop" class="autorun_user_chk btn-check" data-key="develop" name="autorun_user[]" value="develop"><label class="btn btn-secondary" for="autorun_develop">내정</label> <input type="checkbox" id="autorun_develop" class="autorun_user_chk btn-check" data-key="develop" name="autorun_user[]" value="develop" checked><label class="btn btn-secondary" for="autorun_develop">내정</label>
<input type="checkbox" id="autorun_warp" class="autorun_user_chk btn-check" data-key="warp" name="autorun_user[]" value="warp"><label class="btn btn-secondary" for="autorun_warp">순간이동</label> <input type="checkbox" id="autorun_warp" class="autorun_user_chk btn-check" data-key="warp" name="autorun_user[]" value="warp" checked><label class="btn btn-secondary" for="autorun_warp">순간이동</label>
<input type="checkbox" id="autorun_recruit" class="autorun_user_chk btn-check" data-key="recruit" name="autorun_user[]" value="recruit"><label class="btn btn-secondary" for="autorun_recruit">징병</label> <input type="checkbox" id="autorun_recruit" class="autorun_user_chk btn-check" data-key="recruit" name="autorun_user[]" value="recruit" checked><label class="btn btn-secondary" for="autorun_recruit">징병</label>
<input type="checkbox" id="autorun_recruit_high" class="autorun_user_chk btn-check" data-key="recruit_high" name="autorun_user[]" value="recruit_high"><label class="btn btn-secondary" for="autorun_recruit_high">모병</label> <input type="checkbox" id="autorun_recruit_high" class="autorun_user_chk btn-check" data-key="recruit_high" name="autorun_user[]" value="recruit_high" checked><label class="btn btn-secondary" for="autorun_recruit_high">모병</label>
<input type="checkbox" id="autorun_train" class="autorun_user_chk btn-check" data-key="train" name="autorun_user[]" value="train"><label class="btn btn-secondary" for="autorun_train">훈사</label> <input type="checkbox" id="autorun_train" class="autorun_user_chk btn-check" data-key="train" name="autorun_user[]" value="train" checked><label class="btn btn-secondary" for="autorun_train">훈사</label>
<input type="checkbox" id="autorun_battle" class="autorun_user_chk btn-check" data-key="battle" name="autorun_user[]" value="battle"><label class="btn btn-secondary" for="autorun_battle">출병</label> <input type="checkbox" id="autorun_battle" class="autorun_user_chk btn-check" data-key="battle" name="autorun_user[]" value="battle" checked><label class="btn btn-secondary" for="autorun_battle">출병</label>
<input type="checkbox" id="autorun_chief" class="autorun_user_chk btn-check" data-key="chief" name="autorun_user[]" value="chief"><label class="btn btn-secondary" for="autorun_chief">기본 사령턴</label> <input type="checkbox" id="autorun_chief" class="autorun_user_chk btn-check" data-key="chief" name="autorun_user[]" value="chief" checked><label class="btn btn-secondary" for="autorun_chief">기본 사령턴</label>
</div> </div>
</div> </div>
</div> </div>
@@ -162,7 +165,7 @@ if ($session->userGrade < 5 && !$allowReset) {
<option value="480">8시간</option> <option value="480">8시간</option>
<option value="600">10시간</option> <option value="600">10시간</option>
<option value="720">12시간</option> <option value="720">12시간</option>
<option value="1440">24시간</option> <option value="1440" selected>24시간</option>
<option value="2160">36시간</option> <option value="2160">36시간</option>
<option value="2880">48시간</option> <option value="2880">48시간</option>
<option value="3600">60시간</option> <option value="3600">60시간</option>
@@ -194,17 +197,11 @@ if ($session->userGrade < 5 && !$allowReset) {
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label for="tournament_trig" class="col-sm-3 col-form-label"><span class="text-nowrap">토너먼트 자동 시작</span> <span class="text-nowrap">경기 단위</span></label> <label for="tournament_trig" class="col-sm-3 col-form-label"><span class="text-nowrap">토너먼트 자동 시작</span></label>
<div class="col-sm-9" id="tournament_trig"> <div class="col-sm-9" id="tournament_trig">
<div id="tournament_trig" class="btn-group-toggle btn-group flex-wrap" data-bs-toggle="buttons"> <div id="tournament_trig" class="btn-group-toggle btn-group flex-wrap" data-bs-toggle="buttons">
<input type="radio" class="btn-check" id="tournament_trig_0" name="tournament_trig" value="0"><label for="tournament_trig_0" class="btn btn-secondary w-25">안함</label> <input type="radio" class="btn-check" id="tournament_trig_0" name="tournament_trig" value="0"><label for="tournament_trig_0" class="btn btn-secondary w-25">수동</label>
<input type="radio" class="btn-check" id="tournament_trig_1" name="tournament_trig" value="1"><label for="tournament_trig_1" class="btn btn-secondary w-25">12분(총 5일)</label> <input type="radio" class="btn-check" id="tournament_trig_1" name="tournament_trig" checked value="1"><label for="tournament_trig_1" class="btn btn-secondary w-25">자동</label>
<input type="radio" class="btn-check" id="tournament_trig_2" name="tournament_trig" value="2"><label for="tournament_trig_2" class="btn btn-secondary w-25">7분(총 10시간)</label>
<input type="radio" class="btn-check" id="tournament_trig_3" name="tournament_trig" value="3"><label for="tournament_trig_3" class="btn btn-secondary w-25">3분(총 4시간)</label>
<input type="radio" class="btn-check" id="tournament_trig_4" name="tournament_trig" value="4" checked><label for="tournament_trig_4" class="btn btn-secondary w-25">1분(총 82분)</label>
<input type="radio" class="btn-check" id="tournament_trig_5" name="tournament_trig" value="5"><label for="tournament_trig_5" class="btn btn-secondary w-25">30초(총 41분)</label>
<input type="radio" class="btn-check" id="tournament_trig_6" name="tournament_trig" value="6"><label for="tournament_trig_6" class="btn btn-secondary w-25">15초(총 21분)</label>
<input type="radio" class="btn-check" id="tournament_trig_7" name="tournament_trig" value="7"><label for="tournament_trig_7" class="btn btn-secondary w-25">5초(총 7분)</label>
</div> </div>
</div> </div>
</div> </div>
+3 -2
View File
@@ -21,6 +21,7 @@ if ($session->userGrade == 5) {
<head> <head>
<title>설치</title> <title>설치</title>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="color-scheme" content="dark">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
<?= WebUtil::printJS('../d_shared/common_path.js') ?> <?= WebUtil::printJS('../d_shared/common_path.js') ?>
@@ -31,8 +32,8 @@ if ($session->userGrade == 5) {
<body> <body>
<div class="container" style="min-width:720px;"> <div class="container" style="min-width:720px;">
<h1 class="row justify-content-md-center">삼국지 모의전투 HiDCHe 리셋</h1> <h1 class="row justify-content-lg-center">삼국지 모의전투 HiDCHe 리셋</h1>
<div class="row justify-content-md-center"> <div class="row justify-content-lg-center">
<div class="col col-lg-8"> <div class="col col-lg-8">
<div class="card" id="db_form_card"> <div class="card" id="db_form_card">
+2 -2
View File
@@ -56,7 +56,7 @@ else if(
$status = 'closed'; $status = 'closed';
} }
else if( else if(
$isUnited > 0 && $isUnited > 0 &&
$now->getTimestamp() - $lastTurn->getTimestamp() > ($reservedDate->getTimestamp() - $now->getTimestamp()) * 2 $now->getTimestamp() - $lastTurn->getTimestamp() > ($reservedDate->getTimestamp() - $now->getTimestamp()) * 2
){ ){
//천통 & 비정지 상태 & 2/3 넘음 //천통 & 비정지 상태 & 2/3 넘음
@@ -88,7 +88,7 @@ $result = ResetHelper::buildScenario(
$options['block_general_create'], $options['block_general_create'],
$options['npcmode'], $options['npcmode'],
$options['show_img_level'], $options['show_img_level'],
$options['tournament_trig'], !!$options['tournament_trig'],
$options['join_mode'], $options['join_mode'],
$options['starttime'], $options['starttime'],
$options['autorun_user']?:null $options['autorun_user']?:null
-76
View File
@@ -1,76 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
WebUtil::requireAJAX();
$betTarget = Util::getPost('target', 'int', -1);
$betGold = Util::getPost('amount', 'int', 0);
if($betTarget < 0 || $betTarget >= 16 || $betGold < 10 || $betGold > 1000){
Json::die([
'result'=>false,
'reason'=>'올바르지 않은 입력입니다'
]);
}
//로그인 검사
$session = Session::requireGameLogin()->setReadOnly();
$userID = Session::getUserID();
$generalID = $session->generalID;
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
increaseRefresh("베팅", 1);
$tournament = $gameStor->tournament;
if($tournament != 6) {
Json::die([
'result'=>false,
'reason'=>'베팅 기간이 아닙니다.'
]);
}
$myGold = $db->queryFirstField('SELECT gold FROM general WHERE no = %i', $generalID);
$bets = $db->queryFirstList('SELECT * FROM betting WHERE general_id = %i', $generalID);
$bets = array_splice($bets, -16);
$totalBet = array_sum($bets);
$oldBet = $bets[$betTarget];
$targetKey = "bet{$betTarget}";
if($myGold - $betGold < 500){
Json::die([
'result'=>false,
'reason'=>'여유 자금이 부족합니다.'
]);
}
if($betGold + $totalBet > 1000){
Json::die([
'result'=>false,
'reason'=>'베팅 허용 금액을 초과했습니다.'
]);
}
$db->update('betting', [
$targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold),
], 'general_id = %i', $generalID);
$db->update('general', [
'gold'=>$db->sqleval('gold - %i', $betGold),
], 'no = %i', $generalID);
$db->update('rank_data', [
'value'=>$db->sqleval('value + %i', $betGold)
], 'general_id = %i AND type = "betgold"', $generalID);
$db->update('betting', [
$targetKey=>$db->sqleval('%b + %i', $targetKey, $betGold)
], 'general_id = 0');
Json::die([
'result'=>true,
'reason'=>'SUCCESS'
]);
+7 -4
View File
@@ -17,10 +17,13 @@ $text = Util::getPost('text');
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow('SELECT no, nation, name, officer_level, permission, con, turntime, belong, penalty, `picture`,`imgsvr` FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, name, officer_level, permission, refresh_score, turntime, belong, penalty, `picture`,`imgsvr` FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -50,7 +53,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
else if ($isSecretBoard && $permission < 2) { else if ($isSecretBoard && $permission < 2) {
Json::die([ Json::die([
+7 -4
View File
@@ -16,10 +16,13 @@ $text = Util::getPost('text');
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow('SELECT no, nation, name, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, name, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -58,7 +61,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
else if ($isSecretBoard && $permission < 2) { else if ($isSecretBoard && $permission < 2) {
Json::die([ Json::die([
+7 -5
View File
@@ -16,11 +16,14 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
increaseRefresh("회의실", 1); increaseRefresh("회의실", 1);
$me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -33,7 +36,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
else if ($isSecretBoard && $permission < 2) { else if ($isSecretBoard && $permission < 2) {
Json::die([ Json::die([
@@ -72,4 +75,3 @@ Json::die([
'articles'=>$articles, 'articles'=>$articles,
'reason'=>'success' 'reason'=>'success'
]); ]);
-61
View File
@@ -1,61 +0,0 @@
<?php
namespace sammo;
include "lib.php";
include "func.php";
WebUtil::requireAJAX();
$availableDieImmediately = false;
//로그인 검사
$session = Session::requireGameLogin();
$userID = Session::getUserID();
$db = DB::db();
$gameStor = KVStorage::getStorage($db, 'game_env');
$general = $db->queryFirstRow('SELECT no,name,owner_name,npc,lastrefresh FROM general WHERE owner=%i AND npc = 0', $userID);
if(!$general){
Json::die([
'result'=>false,
'reason'=>'장수가 없습니다.'
]);
}
increaseRefresh("장수 삭제", 1);
$gameStor->cacheValues(['turnterm', 'opentime', 'turntime', 'year', 'month']);
if($gameStor->turntime > $gameStor->opentime){
Json::die([
'result'=>false,
'reason'=>'이미 서버가 시작되었습니다.'
]);
}
$targetTime = addTurn($general['lastrefresh'], $gameStor->turnterm, 2);
if($targetTime > TimeUtil::now()){
$targetTimeShort = substr($targetTime, 0, 19);
Json::die([
'result'=>false,
'reason'=>"아직 삭제할 수 없습니다. {$targetTimeShort} 부터 가능합니다."
]);
}
$generalObj = General::createGeneralObjFromDB($general['no']);
if($generalObj instanceof DummyGeneral){
trigger_error("올바르지 않은 삭제 프로세스 $userID", E_USER_WARNING);
}
$generalName = $generalObj->getName();
$josaYi = JosaUtil::pick($generalName, '이');
$generalObj->kill($db, true, "<Y>{$generalName}</>{$josaYi} 이 홀연히 모습을 <R>감추었습니다</>");
$session->logoutGame();
Json::die([
'result'=>true,
'reason'=>'success'
]);
+11 -6
View File
@@ -1,6 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -15,10 +17,13 @@ $letterNo = Util::getPost('letterNo', 'int');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -100,7 +105,7 @@ if(in_array($stateOpt, ['try_destroy_src', 'try_destroy_dest'])){
'reason'=>'파기' 'reason'=>'파기'
]; ];
} }
$msgText = "외교 서신 #{$letterNo} 파기했습니다."; $msgText = "외교 서신(#{$letterNo})을 파기했습니다.";
$lastState = 'cancelled'; $lastState = 'cancelled';
} }
else{ else{
@@ -114,12 +119,12 @@ else{
'aux'=>Json::encode($aux) 'aux'=>Json::encode($aux)
], 'no=%i', $letterNo); ], 'no=%i', $letterNo);
$msgText = "외교 서신 #{$letterNo} 파기 요청합니다."; $msgText = "외교 서신(#{$letterNo})을 파기 요청합니다.";
$lastState = 'activated'; $lastState = 'activated';
} }
$msg = new Message( $msg = new Message(
Message::MSGTYPE_DIPLOMACY, MessageType::diplomacy,
$src, $src,
$dest, $dest,
$msgText, $msgText,
+7 -5
View File
@@ -16,11 +16,14 @@ $isSecretBoard = Util::getPost('isSecret', 'bool', false);
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, nation, officer_level, permission, con, turntime, belong, penalty FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, nation, officer_level, permission, refresh_score, turntime, belong, penalty FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -33,7 +36,7 @@ if($permission < 0){
'result'=>false, 'result'=>false,
'reason'=>'국가에 소속되어있지 않습니다.' 'reason'=>'국가에 소속되어있지 않습니다.'
]); ]);
} }
$letters = []; $letters = [];
@@ -83,4 +86,3 @@ Json::die([
'myNationID'=>$me['nation'], 'myNationID'=>$me['nation'],
'reason'=>'success' 'reason'=>'success'
]); ]);
+12 -7
View File
@@ -1,6 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -20,10 +22,13 @@ $reason = Util::getPost('reason', 'string', '');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -85,7 +90,7 @@ if($isAgree){
], 'no=%i', $prevLetterNo); ], 'no=%i', $prevLetterNo);
$prevLetterNo = $db->queryFirstField('SELECT prev_no FROM ng_diplomacy WHERE state != \'cancelled\' AND no = %i', $prevLetterNo); $prevLetterNo = $db->queryFirstField('SELECT prev_no FROM ng_diplomacy WHERE state != \'cancelled\' AND no = %i', $prevLetterNo);
} }
$msgText = "외교 서신 #{$letterNo} 승인되었습니다."; $msgText = "외교 서신( #{$letterNo})이 승인되었습니다.";
} }
else{ else{
$aux['reason'] = [ $aux['reason'] = [
@@ -97,14 +102,14 @@ else{
'state'=>'cancelled', 'state'=>'cancelled',
'aux'=>Json::encode($aux) 'aux'=>Json::encode($aux)
], 'no=%i', $letterNo); ], 'no=%i', $letterNo);
$msgText = "외교 서신 #{$letterNo} 거부되었습니다."; $msgText = "외교 서신(#{$letterNo})이 거부되었습니다.";
if($reason){ if($reason){
$msgText .= ' 이유 : '.$reason; $msgText .= ' 이유 : '.$reason;
} }
} }
$msg = new Message( $msg = new Message(
Message::MSGTYPE_DIPLOMACY, MessageType::diplomacy,
$src, $src,
$dest, $dest,
$msgText, $msgText,
@@ -115,7 +120,7 @@ $msg = new Message(
$msgID = $msg->send(); $msgID = $msg->send();
$msg = new Message( $msg = new Message(
Message::MSGTYPE_NATIONAL, MessageType::national,
$src, $src,
$dest, $dest,
$msgText, $msgText,
+11 -8
View File
@@ -1,6 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -15,10 +17,13 @@ $letterNo = Util::getPost('letterNo', 'int');
increaseRefresh("외교부", 1); increaseRefresh("외교부", 1);
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -41,8 +46,6 @@ if ($permission < 4) {
]); ]);
} }
$reason = trim($reason);
$letter = $db->queryFirstRow('SELECT * FROM ng_diplomacy WHERE no=%i AND src_nation_id = %i AND state = \'proposed\'', $letterNo, $me['nation']); $letter = $db->queryFirstRow('SELECT * FROM ng_diplomacy WHERE no=%i AND src_nation_id = %i AND state = \'proposed\'', $letterNo, $me['nation']);
if(!$letter){ if(!$letter){
Json::die([ Json::die([
@@ -66,16 +69,16 @@ $unlimited = new \DateTime('9999-12-31');
$aux['reason'] = [ $aux['reason'] = [
'who'=>$me['no'], 'who'=>$me['no'],
'action'=>'cancelled', 'action'=>'cancelled',
'reason'=>$reason 'reason'=>'회수',
]; ];
$db->update('ng_diplomacy', [ $db->update('ng_diplomacy', [
'state'=>'cancelled', 'state'=>'cancelled',
'aux'=>Json::encode($aux) 'aux'=>Json::encode($aux)
], 'no=%i', $letterNo); ], 'no=%i', $letterNo);
$msgText = "외교 서신 #{$letterNo} 회수되었습니다."; $msgText = "외교 서신(#{$letterNo})이 회수되었습니다.";
$msg = new Message( $msg = new Message(
Message::MSGTYPE_DIPLOMACY, MessageType::diplomacy,
$src, $src,
$dest, $dest,
$msgText, $msgText,
+9 -4
View File
@@ -1,6 +1,8 @@
<?php <?php
namespace sammo; namespace sammo;
use sammo\Enums\MessageType;
include "lib.php"; include "lib.php";
include "func.php"; include "func.php";
@@ -22,10 +24,13 @@ if($prevNo < 1){
$prevNo = null; $prevNo = null;
} }
$me = $db->queryFirstRow('SELECT no, name, nation, officer_level, permission, con, turntime, belong, penalty, picture, imgsvr FROM general WHERE owner=%i', $userID); $me = $db->queryFirstRow(
'SELECT no, name, nation, officer_level, permission, refresh_score, turntime, belong, penalty, picture, imgsvr FROM `general`
LEFT JOIN general_access_log AS l ON `general`.no = l.general_id WHERE owner=%i', $userID
);
$con = checkLimit($me['con']); $limitState = checkLimit($me['refresh_score']);
if ($con >= 2) { if ($limitState >= 2) {
Json::die([ Json::die([
'result'=>false, 'result'=>false,
'reason'=>'접속 제한입니다.' 'reason'=>'접속 제한입니다.'
@@ -176,7 +181,7 @@ else{
$msg = new Message( $msg = new Message(
Message::MSGTYPE_DIPLOMACY, MessageType::diplomacy,
$src, $src,
$dest, $dest,
$msgText, $msgText,

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