-
[OpenSource] Unlight 오픈소스 게임 - playOpenSource 2024. 1. 15. 16:17
설치는 완료했지만 사실 플레이하면 계정 생성, 퀘스트, 레이드, 듀얼은 정상 동작하지 않는다.
오픈 소스 출처
https://github.com/open-unlight/legacy-unlight-docker
0. 설치 포스팅
https://heehee-myblog.tistory.com/67
1. 계정 생성 방법
1.1 연결 에러시 확인
로그인창 아래에 create new account를 눌렀는데 생성이 성공이 안뜨고 연결 에러 알림이 뜨는경우
// 현재 떠있는 도커 컨테이너들중에 unlight auth-server와 다른 컨테이너들이 있는지 확인한다. sudo docker ps
1.2 계정 생성 중 진행 안되는 에러
계정 정보 입력 후 카드 선택후 OK 눌렀는데 다음 화면으로 넘어가지 않는경우
1.3 에러 로그 확인
서버 에러 확인 커맨드
// 데이터 서버를 예시로 로그 정보 확인 // logs -f [컨테이너 이름]을 적으면 서버 별로 디버깅 할 수 있다. // unlight-game_server-1, unlight-quest_server-1 ... sudo docker logs -f unlight-auth_server-1
이 경우는 로그를 확인해서 알게됬는데 DB에 캐릭터, 인벤토리, 아이템, 이벤트 카드등에 기본 정보가 없어서 발생한 문제였다.
즉 DB가 현재 텅빈 상태인데 원래 비워져있는게 정상인지 아니면 에러로 데이터 import가 잘못 된건지 소스 분석이 다 안되서 잘 모르겠다.
1.4 백업 데이터 위치 확인 (CSV)
해결방법은 DB에 데이터를 import 해주면 된다.
데이터가 있는 위치로 이동한다.
데이터가 있는지 확인하다. (실제 import한 데이터)
// csv 디렉토리 하위에 언어별로 kr, en, fr 등이 있는데 ja가 데이터가 제일 많이 백업 되어있어서 ja로 이동 cd /legacy-unlight-docker/src/app/server/data/csv/ja
1.5 DB 아이피 확인
// 도커 네트워크 목록 확인 작업 sudo docker network list // unlight_default를 확인한다. sudo docker network inspect unlight_default
아래 목록에서 unlight-db-1을 찾고 IPv4Address를 기억해둔다. 172.19.0.3
IP는 도커가 뜰때마다 자동할당되므로 매번 다를 수 있다.
1.6 DB 접속 (DB 툴 사용)
DataGrip 기준으로 csv 데이터를 import하는 방법 ( 사용하는 DB 툴에 따라 import방법이 다르다)
DataGrip 클릭후 아래와같이 입력한다.
DB 계정 정보는 legacy-unlight-docker/server.env 파일에 나와있다.
id : unlight
pwd: unlight
+
database: unlight_db
rootPwd: unlight
1.7 Import Data
database 선택후 import할 테이블을 아래와 같이 우측 클릭한다.
Import/Export -> Import Data from Files
테이블명이 같은 /legacy-unlight-docker/src/app/server/data/csv/ja의 파일을 import해준다.
import 파일을 선택하면 아래와 같은 테이블 컬럼과 csv파일 컬럼 맵핑 화면이 나오는데
좌측에 표시된 빨간 박스 부분에 Firt row is header로 클릭했는지 확인하고
우측 빨간 박스에 mapped to xxxx 가 DB 컬럼과 잘 맞는지 확인한다.
현재는 우측 빨간박스 맨밑에 mapped to caption_kr이 테이블의 created_at과 맵핑되어져 잘못된 값이 들어간다.
따라서 해당 값을 더블클릭해 지워주면 된다.
caption값이 현재 일본어로 되어있는데 caption_kr로 바꿔서 맵핑해줘도 된다.
위와같은 방법으로 /legacy-unlight-docker/src/app/server/data/csv/ja의 파일을 전부 import 해준다.
그리고 commit도 혹시 모르니 해준다.
1.8 동작 확인
로그인하면 캐릭터 생성화면에서 잘 넘어가는걸 확인 할 수 있다.
2. 다크룸 티켓 생성
다크룸만되면 사실 게임 끝일지도..모르지만 티켓 정보를 DB에서 찾기는 생각보다 어려웠다.
찾고 보니 일반적인 테이블 구조가 아닌 것 같았다.
로그 관리 목적이면 따로 로그 테이블을 하나 만드는게 좋지 않았나 싶다.
2.1 아이템 테이블 조회
// 아이템 정보 테이블 조회 // 여기에는 티켓이 9번 id라는데 어느 테이블 FK인지 보이지않았다. select * from unlight_db.avatar_items;
2.2 유저 인벤토리 테이블
인벤토리 테이블은 item_inventories 였다.
분명히 다크룸 티켓이 40개가 있는데 어느 테이블의 row에도 40이 찍혀있지 않았다
그러던 중에 item_inventories에 9라는 id를 찾아서 갯수를 세보니 40개 였다.
count 컬럼이 따로 없고 티켓이 40개면 40개의 row를 차지 하는 것이다
테이블을 저렇게 만든 의도는 여러 방면에서 궁금했지만 여튼 빠른 게임 진행을 위해 GPT의 도움을 받아 빠르게 프로시저를 하나 생성했다
2.3 유틸용 프로시저 생성
// 프로시저 생성 DELIMITER // CREATE PROCEDURE InsertManyTimes(IN num_times INT) BEGIN DECLARE v_counter INT DEFAULT 0; WHILE v_counter < num_times DO INSERT INTO unlight_db.item_inventories (avatar_id, avatar_item_id, state, server_type, use_at, created_at, updated_at) VALUES (1, 9, 0, 0, null, null, null); SET v_counter = v_counter + 1; END WHILE; END // DELIMITER ; // 사용 예시 ( 아바타ID, 티켓 생성 할 수량) call unlight_db.InsertManyTimes(1,100);
2.4 테이블명 규칙
테이블을 분석하다보니 찾은 규칙이 있는데
테이블 명 뒤에 _inventories라고 붙은게 전부 유저의 아이템에 맵핑 되는 부분을 의미한다.
예시)
select * from chara_card_slot_inventories;
select * from item_inventories;
select * from card_inventories;
3. 퀘스트 하는 방법
퀘스트를 실행하면 다음과같은 화면에서 멈추는 걸 확인 할 수 있다.
3.1 서버 로그 확인
따라서 도커 컨테이너의 로그를 확인해야한다.
sudo docker logs -f unlight-quest_server-1
로그에 아래와 같이 출력됬다.
/app/server/src/model/cpu_card_data.rb:159:in equip_cards_id': undefined method split' for nil:NilClass (NoMethodError)
3.2 임시 에러 수정
주의 : 정확히 분석하지 않고 nil 처리를 위한 예외작업만 했기 때문에 추후 오류 재발시 코드 분석이 필요하다.
src/app/server/src/model/cpu_card_data.rb 를 vscode로 연다.
equip_cards_id, weapon_cards_id, event_cards_id 메서드를 찾는다.
null처리를 해줘야하는데 왜 nil이 발생하는지는 아직 분석을 제대로 못해서 알 수 없지만 초기에 cpu라는 컴퓨터 계정 데이터가 초기화될때 특정 카드를 찾지못해서 나는 에러로 추정된다.
일단 없는카드는 알 수 없으니 두고 아래와 같이 코드를 수정하면 퀘스트는 정상 실행된다.
아마 특정 맵에서 안될거라고 예상되지만 아직까지 딱히 문제 되지는 않았다.
# 아래 weapon_cards_id, equip_cards_id, event_cards_id 메서드를 찾아서 다음과 같이 수정한다. def weapon_cards_id ret = [[],[],[]] if self.equip_card_id wcs = self.weapon_card_id.split(/\+/) wcs.each_index do |i| wcs[i].split(/\//).map!{|s|s.to_i}.each do |c| ret[i] << c if c != 0 end end else print " execept test debug " end ret end def equip_cards_id print " debug test " ret = [[],[],[]] if self.equip_card_id ecs = self.equip_card_id.split(/\+/) ecs.each_index do |i| ecs[i].split(/\//).map!{|s|s.to_i}.each do |c| ret[i] << c if c != 0 end end else end ret end def event_cards_id ret = [[],[],[]] if self.event_card_id ecs = self.event_card_id.split(/\+/) ecs.each_index do |i| ecs[i].split(/\//).map!{|s|s.to_i}.each do |c| ret[i] << c if c != 0 end end else end ret end
4. 레이드 하는 방법
레이드는 유저 인벤토리에 탐지기 아이템 몇개 추가한 후 새로고침하면 참가할 수 있다.
4.1 서버 오류 로그 확인
// 에러 로그 확인 방법 sudo docker logs -f unlight-raid_server-1
sql에서 group by 없이 집계함수인 sum을 사용해서 나는 에러이다.
쿼리를 수정하기는 분석이 안되서 위험이 있을것같아서 mysql 설정을 수정했다.
Mysql2::Error: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'unlight_db.profound_logs.id'; this is incompatible with sql_mode=only_full_group_by: SELECT *, sum(damage) AS sum_damage FROM profound_logs WHERE ((profound_id = 2) AND (avatar_id > 0))
4.2 해결 방법
레이드의 경우는 간단하게 mysql 설정만 수정해주면된다. (참고로 클로바 5나 특정 카드는 사용이 불가하여 레이드에서 에러 난다)
// 아래 디렉토리로 이동한다. cd /legacy-unlight-docker/db/conf.d // my.cnf 파일을 생성한다. vi my.cnf 아래 정보를 넣는다. ; my.cnf [mysqld] sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' character-set-server=utf8mb4 collation-server=utf8mb4_unicode_ci init_connect='SET NAMES utf8mb4' [client] default-character-set=utf8mb4 [mysql] default-character-set=utf8mb4 // 위에 정보로 파일을 생성한다. ( sql_mode 에서 ONLY_FULL_GROUP_BY만 제거하고 넣는다 ) // 그리고 서버를 재시작해준다. sudo make restart
5. 개발시
언라이트 프로젝트에 대해서 분석하려면 루비와 레일즈와 소켓 그리고 액션 스크립트에 대한 이해가 필요하다.
도커 이미지로 만들어져서 비교적 쉽게 로컬 환경에서는 진행할 수 있지만 실제 유지보수와 개발에 있어서는 GPT에 의존하는게 한계가 있어서 공부가 필요하다.
6. 퀘스트 영상
7. 레이드 영상
8. 다크룸 영상
'OpenSource' 카테고리의 다른 글
[OpenSource] Unlight 오픈소스 게임 - install (0) 2024.01.14