diff --git a/docs/INSTALL_WINDOWS.md b/docs/INSTALL_WINDOWS.md index e88def3..b976b26 100644 --- a/docs/INSTALL_WINDOWS.md +++ b/docs/INSTALL_WINDOWS.md @@ -10,11 +10,11 @@ This step-by-step guide assumes that you are using a fresh install of Windows 10 3. Make sure that you enable "Create shortcuts for installed applications" and "Add Python to environment variables" and hit Install ## Install MySQL 8.0 -1. Download MySQL 8.0 Server : [Link](https://cdn.mysql.com//Downloads/MySQLInstaller/mysql-installer-web-community-8.0.31.0.msi) -2. Install mysql-installer-web-community-8.0.31.0.msi +1. Download MySQL 8.0 Server : [Link](https://dev.mysql.com/get/Downloads/MySQLInstaller/mysql-installer-community-8.0.34.0.msi) +2. Install mysql-installer-web-community-8.0.34.0.msi 1. Click on "Add ..." on the side 2. Click on the "+" next to MySQL Servers - 3. Make sure MySQL Server 8.0.29 - X64 is under the products to be installed. + 3. Make sure MySQL Server 8.0.34 - X64 is under the products to be installed. 4. Hit Next and Next once installed 5. Select the configuration type "Development Computer" 6. Hit Next @@ -23,9 +23,10 @@ This step-by-step guide assumes that you are using a fresh install of Windows 10 9. Leave everything under Windows Service as default and hit Next > 10. Click on Execute and for it to finish and hit Next> and then Finish 3. Open MySQL 8.0 Command Line Client and login as your root user -4. Type those commands to create your user and the database -``` -CREATE USER 'aime'@'localhost' IDENTIFIED BY 'MyStrongPass.'; +4. Change `` to a new password for the user aime, type those commands to create your user and the database + +```sql +CREATE USER 'aime'@'localhost' IDENTIFIED BY ''; CREATE DATABASE aime; GRANT Alter,Create,Delete,Drop,Index,Insert,References,Select,Update ON aime.* TO 'aime'@'localhost'; FLUSH PRIVILEGES; @@ -34,33 +35,50 @@ exit; ## Install Python modules 1. Change your work path to the artemis-master folder using 'cd' and install the requirements: -> pip install -r requirements.txt -## Copy/Rename the folder example_config to config +```shell +pip install -r requirements.txt +``` -## Adjust /config/core.yaml +## Copy/Rename the folder `example_config` to `config` -1. Make sure to change the server listen_address to be set to your local machine IP (ex.: 192.168.1.xxx) +## Adjust `config/core.yaml` + +1. Make sure to change the server `hostname` to be set to your local machine IP (ex.: 192.168.xxx.xxx) - In case you want to run this only locally, set the following values: -``` + +```yaml server: listen_address: 0.0.0.0 title: - hostname: localhost + hostname: 192.168.xxx.xxx +``` + +1. Adjust the proper MySQL information you created earlier +```yaml +database: + host: "localhost" + username: "aime" + password: "" + name: "aime" ``` -2. Adjust the proper MySQL information you created earlier 3. Add the AimeDB key at the bottom of the file 4. If the webui is needed, change the flag from False to True ## Create the database tables for ARTEMiS -> python dbutils.py create + +```shell +python dbutils.py create +``` ## Firewall Adjustements Make sure the following ports are open both on your router and local Windows firewall in case you want to use this for public use (NOT recommended): > Port 80 (TCP), 443 (TCP), 8443 (TCP), 22345 (TCP), 8080 (TCP), 8090 (TCP) **webui, 8444 (TCP) **mucha ## Running the ARTEMiS instance -> python index.py +```shell +python index.py +``` # Troubleshooting @@ -78,6 +96,7 @@ Make sure the following ports are open both on your router and local Windows fir ## AttributeError: module 'collections' has no attribute 'Hashable' 1. This means the pyYAML module is obsolete, simply rerun pip with the -U (force update) flag, as shown below. - Change your work path to the artemis-master (or artemis-develop) folder using 'cd' and run the following commands: -``` + +```shell pip install -r requirements.txt -U ``` diff --git a/docs/game_specific_info.md b/docs/game_specific_info.md index c328ce2..615f10b 100644 --- a/docs/game_specific_info.md +++ b/docs/game_specific_info.md @@ -571,32 +571,34 @@ python dbutils.py --game SDGT upgrade ### Item categories -1. D Coin -3. Car Dressup Token -5. Avatar Dressup Token -6. Tachometer -7. Aura -8. Aura Color -9. Avatar Face -10. Avatar Eye -11. Avatar Mouth -12. Avatar Hair -13. Avatar Glasses -14. Avatar Face accessories -15. Avatar Body -18. Avatar Background -21. Chat Stamp -22. Keychain -24. Title -25. Full Tune Ticket -26. Paper Cup -27. BGM -28. Drifting Text -31. Start Menu BG -32. Car Color/Paint -33. Aura Level? -34. Full Tune Ticket Fragment -35. Underneon Lights +| Category ID | Category Name | +| ----------- | ------------------------ | +| 1 | D Coin | +| 3 | Car Dressup Token | +| 5 | Avatar Dressup Token | +| 6 | Tachometer | +| 7 | Aura | +| 8 | Aura Color | +| 9 | Avatar Face | +| 10 | Avatar Eye | +| 11 | Avatar Mouth | +| 12 | Avatar Hair | +| 13 | Avatar Glasses | +| 14 | Avatar Face accessories | +| 15 | Avatar Body | +| 18 | Avatar Background | +| 21 | Chat Stamp | +| 22 | Keychain | +| 24 | Title | +| 25 | FullTune Ticket | +| 26 | Paper Cup | +| 27 | BGM | +| 28 | Drifting Text | +| 31 | Start Menu BG | +| 32 | Car Color/Paint | +| 33 | Aura Level | +| 34 | FullTune Ticket Fragment | +| 35 | Underneon Lights | ### TimeRelease Chapter: diff --git a/example_config/idac.yaml b/example_config/idac.yaml index 04ea1e0..331ae82 100644 --- a/example_config/idac.yaml +++ b/example_config/idac.yaml @@ -1,6 +1,6 @@ server: enabled: True - loglevel: "debug" + loglevel: "info" ssl: False ssl_key: "cert/idac.key" ssl_cert: "cert/idac.crt" diff --git a/titles/idac/season2.py b/titles/idac/season2.py index 3142d49..5717978 100644 --- a/titles/idac/season2.py +++ b/titles/idac/season2.py @@ -75,32 +75,32 @@ class IDACSeason2(IDACBase): def handle_boot_getconfigdata_request(self, data: Dict, headers: Dict): """ category: - 1 = D Coin - 3 = Car Dressup Token - 5 = Avatar Dressup Token - 6 = Tachometer - 7 = Aura - 8 = Aura Color - 9 = Avatar Face - 10 = Avatar Eye - 11 = Avatar Mouth - 12 = Avatar Hair - 13 = Avatar Glasses - 14 = Avatar Face accessories - 15 = Avatar Body - 18 = Avatar Background - 21 = Chat Stamp - 22 = Keychain - 24 = Title - 25 = Full Tune Ticket - 26 = Paper Cup - 27 = BGM - 28 = Drifting Text - 31 = Start Menu BG - 32 = Car Color/Paint - 33 = Aura Level? - 34 = Full Tune Ticket Fragment - 35 = Underneon Lights + 1 = D Coin + 3 = Car Dressup Token + 5 = Avatar Dressup Token + 6 = Tachometer + 7 = Aura + 8 = Aura Color + 9 = Avatar Face + 10 = Avatar Eye + 11 = Avatar Mouth + 12 = Avatar Hair + 13 = Avatar Glasses + 14 = Avatar Face accessories + 15 = Avatar Body + 18 = Avatar Background + 21 = Chat Stamp + 22 = Keychain + 24 = Title + 25 = FullTune Ticket + 26 = Paper Cup + 27 = BGM + 28 = Drifting Text + 31 = Start Menu BG + 32 = Car Color/Paint + 33 = Aura Level + 34 = FullTune Ticket Fragment + 35 = Underneon Lights """ version = headers["device_version"] ver_str = version.replace(".", "")[:3] @@ -146,9 +146,9 @@ class IDACSeason2(IDACBase): "round_event_exp": [], "stamp_info": self.stamp_info, # 0 = use default data, 1+ = server version of timereleasedata response - "timerelease_no": 5, + "timerelease_no": 1, # 0 = use default data, 1+ = server version of gachadata response - "timerelease_avatar_gacha_no": 5, + "timerelease_avatar_gacha_no": 1, "takeover_reward": [], "subcard_judge": [ { @@ -316,7 +316,7 @@ class IDACSeason2(IDACBase): # get the country id from the profile, 9 is JPN "country": 9, "style_car_id": rank["style_car_id"], - # convert the dateimt to a timestamp + # convert the datetime to a timestamp "play_dt": int(rank["play_dt"].timestamp()), "section_time_1": rank["section_time_1"], "section_time_2": rank["section_time_2"], @@ -341,7 +341,6 @@ class IDACSeason2(IDACBase): } def handle_login_checklock_request(self, data: Dict, headers: Dict): - access_code = data["accesscode"] user_id = data["id"] # check if an IDAC profile already exists @@ -1576,6 +1575,71 @@ class IDACSeason2(IDACBase): "maker_use_count": [], } + def _generate_time_trial_data(self, season_id: int, user_id: int) -> List[Dict]: + # get the season time trial data from database + timetrial_data = [] + + courses = self.data.item.get_courses(user_id) + if courses is None or len(courses) == 0: + return {"status_code": "0", "timetrial_data": timetrial_data} + + for course in courses: + # grab the course id and course proeficiency + course_id = course["course_id"] + skill_level_exp = course["skill_level_exp"] + + # get the best time for the current course for the current user + best_trial = self.data.item.get_time_trial_best_ranking_by_course(season_id, user_id, course_id) + if not best_trial: + continue + + goal_time = best_trial["goal_time"] + # get the rank for the current course + course_rank = self.data.item.get_time_trial_ranking_by_course( + season_id, course_id, limit=None + ) + course_rank = len([r for r in course_rank if r["goal_time"] < goal_time]) + 1 + + timetrial_data.append( + { + "style_car_id": best_trial["style_car_id"], + "course_id": course_id, + "skill_level_exp": skill_level_exp, + "goal_time": goal_time, + "rank": course_rank, + "rank_dt": int(best_trial["play_dt"].timestamp()), + }) + + return timetrial_data + + def handle_user_getpastseasontadata_request(self, data: Dict, headers: Dict): + user_id = headers["session"] + season_id = data.get("season_id") + + # so to get the season 1 data just subtract 1 from the season id + past_timetrial_data = self._generate_time_trial_data(season_id - 1, user_id) + + # TODO: get the current season timetrial data somehow, because after requesting + # GetPastSeasonTAData the game will NOT request GetTAData?! + return { + "status_code": "0", + "season_id": season_id, + "past_season_timetrial_data": past_timetrial_data, + } + + def handle_user_gettadata_request(self, data: Dict, headers: Dict): + user_id = headers["session"] + + timetrial_data = self._generate_time_trial_data(self.version, user_id) + + # TODO: get the past season timetrial data somehow, because after requesting + # GetTAData the game will NOT request GetPastSeasonTAData?! + return { + "status_code": "0", + "timetrial_data": timetrial_data, + # "past_season_timetrial_data": timetrial_data, + } + def handle_user_updatecartune_request(self, data: Dict, headers: Dict): user_id = headers["session"]