Giter Club home page Giter Club logo

multiworld_client's Introduction

Read Me

Welcome to the Client implementation for the Wind Waker Multiplayer project! Please understand that the project is still under development. At times one aspect may seem more refined than others, and that is to be expected.

Set Up

  1. Run the exe
  2. Select "Join Room"
  3. Select Multiworld or Coop
  4. Your group should have the same Room Name

Player Names are currently Disabled for Multiworld

FAQ

  • Why doesn't X item get shared?
    • If the item isn't from a Chest, then it won't get shared.
  • When will X check get added?
    • There is a massive process for adding in different check types, it will happen eventually, I promise :)

Current Plans

  • Game Room Update to make the Client/Server process more secure, and more personalized.

multiworld_client's People

Contributors

celestialkitsune avatar crain-32 avatar jarheadhme avatar jaysc avatar

Stargazers

 avatar

Watchers

 avatar  avatar

multiworld_client's Issues

Begin preparation for Item Tracking Integration

One of the planned goals of the Client is to integrate at some level with external projects/trackers.

To accomplish this the following will have to be done.
requests >= 2.27.1 should be added to the requirements.txt

The following will need to be added to the config.ini and config.py as aspects of the Global configuration.

[Server]
external_integration =

[Game]
player_name =

In the Model Package, a new file externalIntDto.py should be made. This will be an @dataclass composing the following.

@dataclass
class ExternalIntDto:
   itemId: int           # Should be decently straightforward
   checkName: AnyStr   # Future Feature, use an empty string when declaring for now
   playerName: AnyStr  # This needs to be added to the global config
   gameroom: AnyStr    # This is in the global config

In the Client Package, a new file externalIntegration.py should be made. The following psuedo code can act as a template.

import requests
from dataclasses import asdict

# Get access to configuration here
async def function(item_id: int, location: AnyStr =""):
   externalDto = ExternalIntDto(#Params)
   response = requests.post(#external_integration from config, json=asdict(exteneralDto)
   if response is bad:
     raise Exception  

This function does not need to be tied into anything yet, simply installed to help prepare for integration later.

Make the Client into an Executible

One of the main issues for the end-users is that normal people aren't able to instantly debug dependency issues and Python versions. Unfortunately it is not possible to educate them in proper version handling, so instead we'll have to build an executable.

The purpose of this Issue is to do the required adjustments and configuration in order to use PyInstaller to make the Executable.

Function Return Value Documentation

Each of the functions inside clientSocket.py, windWakerInterface.py, and stompframemanager.py should include return Type hints. Even if it is just None

For example in windWakerInterface.py

def hook():
  dme.hook()
  # Should be
def hook() -> None:
  dme.hook()

Client Deletes Incoming Items

Issue

The current implementation of check_valid_state() -> bool: in windWakerInterface.py doesn't account for certain edge cases. Namely time between saving, stage transitions, and potentially others situations.

Desired Resolution

check_valid_state() -> bool: should return False if giving the item would delete it, meaning the above mentioned situations need to be scanned and prevented.

Potential Tips

You might find it useful to use the GUI version of Dolphin-Memory Engine, in coordination with Frame-Advancing Dolphin, in order to pinpoint invalid frames for giving items, and finding information on the memory that might help track for valid state.

Additional Chart Handling (Multiworld) - NO LONGER NEEDED

Whenever you get any Chart, the Game will reset all the flags for that Chart. This code should only impact Salvageable Charts.

Currently there isn't a handler on this, meaning players can double-salvage certain items, this is the easiest way to duplicate items.

Here are the situations that can come up, and their resolutions. (Assume Charts are not Randomized)

Player A receives Treasure Chart 1 from Player B, and has not found that Chart in their own world.
- Treasure Chart 1's flags are reset. (Mirrors Vanilla Behavior for finding a Chart)

Player A receives Treasure Chart 1 from Player B, and found Player B's Chart in their own world.
- Treasure Chart 1's flags are reset. (The flags should have been handled when sending original chart as well)

Player A sends Treasure Chart 1 to Player B, and has not Salvaged the Chart.
- No flags are changed.

Player A sends Treasure Chart 1 to Player B, and has already Salvaged this Chart.
- Flags are set to the "Salvaged" State.

The easiest way to handle this (Unfortunately) is to run a scan over the memory locations found here whenever a new Item is found. Then when sending a Chart, we verify the status of the Memory. (Reference the Player's Inventory to see if they own the chart -> Verify Memory State -> Adjust if needed)

Note
It might be possible to disable the Game's flag resetting mechanism using ASM patches, meaning we can leave the flag handling entirely to the game. And have no code Changes for the Client. This would also provide a solution to the Randomized Chart Problem.
Before working on this, please DM me on Discord directly asking about it.

Current Item Tracking - Resolved through ASM Patches

Reason

In order for Multiworld to Properly work with the current implementation, the Client needs to know when it should remove Items, and when it should give Items. This helps handle the player getting other player's items.

Expected Implementation

The expectation is a Singleton Class (PlayerInventory? InventoryManager? just make it relevant) with the following functions.

server_received_item(item_id: int,) -> bool:

  • Anytime the Client receives an Item from the Server, this function is called to verify if giving it to the player would result in a duplicate, AND if the player can receive it, then add it to the Player's tracked inventory.
  • If it returns False, then the Client should not send the Item to the AbstractGameHandler, and instead raise a DuplicateItemWarning, otherwise it should give the item to the AbstractGameHandler

server_sent_item(item_id: int) -> bool:

  • Before sending an Item out to the Server this function is called to verify if the Player's Item they received should be removed from their inventory or not.
  • If it returns True, then the Client should tell the AbstractGameHandler to remove the given Item ID from the Player.

found_item(item_id:int) -> None:

  • If the Player finds an Item, but the Item is for the player, the AbstractGameHandler should call this function in order to add it to the tracked Inventory.

current_items() -> dict[str, int]:

  • Returns all the items in a dictionary of the following format
{
  "Item Name": "Amount",
  "Deku Leaf": 1,
  "DRC Small Key": 3,
  # ETC....
}

Example Situations

World One finds a Deku Leaf for World 2. World One already has their Deku Leaf.

  • World One's AbstractGameHandler doesn't call found_item, as this belongs to a different World ID.
  • Before World One sends the Deku Leaf to the Server, it calls server_sent_item, which returns False, as World One doesn't need to lose it's Deku Leaf
  • World Two's Client receives the Deku Leaf, and calls server_received_item, which returns True, so World Two's AbstractGameHandler gets the Deku Leaf, and gives it to the Player.

World Three finds a DRC Small Key for World One, but World One already has 4 Tracked DRC Small Keys, and World Three has 2 Tracked DRC Small Keys

  • World Three's AbstractGameHandler doesn't call found_item, as this belongs to a different World ID.
  • Before World Three sends the DRC Small Key to the Server, it calls server_sent_item, which returns True, and so World Three's AbstractGameHandler removes a DRC Small Key from the Player.
  • World One's Client gets the DRC Small Key and calls server_received_time, which returns False, so the Client raises a DuplicateItemWarning and doesn't give the DRC Small Key to the Player.

Separation of Dolphin and Server Communication

Reason

The current implementation puts both the Server-Client communication with the Client-Dolphin Communication in clientSocket.py, this should instead be refactored into three different files.

clientCommunication.py

This will handle the Client-Server communication. For now a simple copy-paste would work. Future iterations will likely require additional utilization of the stompframemanager.py, as we currently don't communicate with the Server following the proper STOMP guidelines.

abstractGameHandler.py

The eventual Console integration will require a separate Python file to handle its communication, in an effort to prepare for that an AbstractGameHandler class should be created with the following methods.

is_connected() -> bool:
give_item(item_id: int) -> None:
toggle_event(event_type: str, event_index: int, enable: bool) -> None:
get_items() -> dict[int, int]:

dolphinGameHandler.py

This class will be a dolphin-focused implementation of the AbstractGameHandler, and should have all the abstract classes implemented at the very least.

Exceptions

The following should be a list of extensions of RunTimeException|RunTimeWarningthat should be raised in certain events, this will be useful for long-term debugging and end-user experience

CouldNotGiveItemException - If give_item() experiences an unexpected error.
DuplicateItemWarning - If the give_item() would create an invalid item (5th Sword, 4th Bow, Second Grapple, etc)
EventToggleException - If the toggle_event() function experiences an unexpected error.
GameHandlerDisconnectWarning - If the connection between the Client and the AbstractGameHandler fails.
ServerDisconnectWarning - If the connection between the Client and the Server fails.

Add a Proper GUI

Reason

Due to a lack of shell-based programming knowledge among the rising generations, it has become a hard requirement that a program should have a full interactive GUI, the Multiplayer Client being no exception.

Wire Frames

The following screenshots are of files already included in the Client, the next steps are integrating them into the full system.

When launching the Client, this screen should pop up.
image

While playing, it is expected to look something like the following.
image

In the long term, a tab or button in order to customize the miscellaneous options (Random Rupoors, Shared bottles, etc) would be nice, for now we'll leave that in the config.txt.

Data Mapping

Server IP -> Config._ServerAddress
Server Port -> Config._Port
Room Name -> Config._Game_Room
Max Players !-! Currently not mapped, future feature
Player Name !-! Currently not mapped, future feature
World ID -> Config._World_id

Additional Information

The goal of this Issue is not to finish the GUI, simply allow the current code to do the following.

  • Populate the Server IP/Port from the current config.txt
  • "Set-up" should update the config, and would go into client_socket

If possible, the button left button saying "Set-up" should swap to "Join" when the top-left dropdown is on "Connect to Room" instead of "Set-up Room"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.