Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added the autoshop task #208

Merged
merged 4 commits into from
Jan 31, 2025
Merged

feat: Added the autoshop task #208

merged 4 commits into from
Jan 31, 2025

Conversation

dm94
Copy link
Owner

@dm94 dm94 commented Jan 23, 2025

Summary by Sourcery

New Features:

  • Added the AutoShop task to automatically purchase items based on configurable conditions, including quantity, credits, and Uridium.

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
Copy link

sourcery-ai bot commented Jan 23, 2025

Reviewer's Guide by Sourcery

This pull request introduces a new AutoShop task that allows users to automatically buy items from the shop based on specified conditions. It includes configurations for setting the item to buy, quantity, and conditions for purchase. It also adds new configurations and enums to support the new task.

Sequence diagram for AutoShop item purchase process

Loading
sequenceDiagram
    participant AutoShop
    participant BackpageAPI
    participant StatsAPI
    participant HeroItemsAPI
    AutoShop->>StatsAPI: Check credits/uridium
    alt Not enough credits/uridium
        AutoShop->>AutoShop: Update label with error
    else Sufficient funds
        AutoShop->>HeroItemsAPI: Check item quantity conditions
        alt Conditions met
            AutoShop->>BackpageAPI: Send purchase request
            BackpageAPI-->>AutoShop: Purchase response
            alt Purchase successful
                AutoShop->>AutoShop: Update label with success
            else Purchase failed
                AutoShop->>AutoShop: Update label with error
            end
        end
    end

Class diagram for AutoShop and related classes

Loading
classDiagram
    class AutoShop {
        -BackpageAPI backpage
        -PluginAPI api
        -StatsAPI stats
        -HeroItemsAPI items
        -Config config
        -JLabel label
        +setConfig(ConfigSetting)
        +beforeConfig()
        +onTickTask()
        -check(BuyItem)
        -buyItem(ItemSupported, int)
    }
    class BuyItem {
        +boolean enable
        +int timeToCheck
        +int quantity
        +String itemToBuy
        +Condition condition
        +QuantityCondition quantityCondition
    }
    class QuantityCondition {
        +boolean active
        +String item
        +int quantity
    }
    class ItemSupported {
        -String id
        -String category
        -double creditsPrice
        -double uridiumPrice
        +getId()
        +getCategory()
        +getCreditsPrice()
        +getUridiumPrice()
    }
    class Config {
        +BuyItem item1
        +BuyItem item2
        +BuyItem item3
        +BuyItem item4
        +BuyItem item5
    }
    AutoShop ..|> Task
    AutoShop ..|> Configurable
    AutoShop ..|> InstructionProvider
    AutoShop --> Config
    Config --> BuyItem
    BuyItem --> QuantityCondition
    AutoShop ..> ItemSupported

State diagram for AutoShop purchase states

Loading
stateDiagram-v2
    [*] --> CheckConditions
    CheckConditions --> CheckCredits: Conditions met
    CheckConditions --> Wait: Conditions not met
    CheckCredits --> CheckUridium: Has enough credits
    CheckCredits --> NO_CREDITS: Not enough credits
    CheckUridium --> Purchase: Has enough uridium
    CheckUridium --> NO_URI: Not enough uridium
    Purchase --> PURCHASE_SUCCESS: Success
    Purchase --> PURCHASE_ERROR: Error
    NO_CREDITS --> Wait
    NO_URI --> Wait
    PURCHASE_ERROR --> Wait
    PURCHASE_SUCCESS --> Wait
    Wait --> CheckConditions: After timeToCheck

File-Level Changes

Change Details Files
Introduce the AutoShop task with configurable item purchases based on defined conditions.
  • Created the AutoShop class implementing the Task, Configurable, and InstructionProvider interfaces.
  • Implemented the logic to check and buy items based on configured conditions, considering credits, uridium, and item availability.
  • Added methods to update the UI label with the status of the purchase.
  • Implemented methods to check conditions based on item quantity and other configurable conditions.
src/main/java/com/deeme/tasks/autoshop/AutoShop.java
Define configurations for the AutoShop task.
  • Created the Config class to hold configurations for multiple BuyItem instances.
src/main/java/com/deeme/tasks/autoshop/Config.java
Define configurations for individual item purchases.
  • Created the BuyItem class to configure individual item purchases, including quantity, item to buy, and conditions.
src/main/java/com/deeme/tasks/autoshop/BuyItem.java
Define an enum of supported items for purchase.
  • Created the ItemSupported enum listing supported items with their IDs, categories, and prices.
src/main/java/com/deeme/tasks/autoshop/ItemSupported.java
Create a supplier for item selection in the configuration.
  • Created the ItemSupplier class to provide a list of available items for selection in the configuration interface.
src/main/java/com/deeme/tasks/autoshop/ItemSupplier.java
Add a configuration for quantity-based conditions.
  • Created the QuantityCondition class to allow purchases based on the quantity of another item.
src/main/java/com/deeme/tasks/autoshop/QuantityCondition.java
Update the AutoShopDummy class to use the new AutoShop task.
  • Updated the package and class extension to reflect the new AutoShop task.
  • Removed PLUS mark from the feature name.
src/main/java/com/deeme/tasks/AutoShopDummy.java
Update plugin.json to remove PLUS mark from the feature name.
  • Updated the plugin.json file to reflect the removal of PLUS mark from the feature name.
src/main/resources/plugin.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!
  • Generate a plan of action for an issue: Comment @sourcery-ai plan on
    an issue to generate a plan of action for it.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @dm94 - I've reviewed your changes and they look great!

Here's what I looked at during the review
  • 🟡 General issues: 3 issues found
  • 🟢 Security: all looks good
  • 🟡 Review instructions: 8 issues found
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 1 issue found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

return;
}

updateCheckTime(itemConfig);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Move the updateCheckTime call after successful purchase

Updating the check time before attempting the purchase means we'll have to wait for the next interval even if the purchase fails. Consider moving this after the successful purchase.

Suggested implementation:

        if (itemConfig.quantity <= 0) {
            return;
        }

        if (itemConfig.itemToBuy != null && checkNormalCondition(itemConfig)

The updateCheckTime(itemConfig) call should be moved to after the successful purchase is completed. This would likely be:

  1. After all purchase conditions are checked
  2. After the credits are verified to be sufficient
  3. After the actual purchase transaction succeeds
  4. Before any final success state updates

You'll need to add the updateCheckTime(itemConfig) call just before the method returns successfully after completing the purchase.

this.creditsPrice = creditsPrice;
this.uridiumPrice = uridiumPrice;

if (id.contains("ammunition_laser_")) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Consider using a more robust category determination system

The current string-based category determination is fragile and duplicates information. Consider using a dedicated category field in the enum or a more structured approach.

Suggested implementation:

    public enum ItemCategory {
        BATTERY,
        SPECIAL,
        ROCKET
    }

    ItemSupported(String id, double creditsPrice, double uridiumPrice, ItemCategory category) {
        this.id = id;
        this.creditsPrice = creditsPrice;
        this.uridiumPrice = uridiumPrice;
        this.category = category.name().toLowerCase();
    }

This change will require:

  1. Updating all places where ItemSupported is instantiated to include the category parameter
  2. If you need to maintain backward compatibility, you could add a factory method or keep the old constructor and mark it as @deprecated:
@Deprecated
ItemSupported(String id, double creditsPrice, double uridiumPrice) {
    this(id, creditsPrice, uridiumPrice, determineCategory(id));
}

private static ItemCategory determineCategory(String id) {
    if (id.contains("ammunition_laser_")) {
        return ItemCategory.BATTERY;
    } else if (id.contains("equipment_extra_cpu_")) {
        return ItemCategory.SPECIAL;
    }
    return ItemCategory.ROCKET;
}

}
}

private ItemSupported getItemById(String id) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (performance): Consider using a static Map for item lookup instead of iteration

The current implementation iterates through all items on every lookup. Consider using a static Map<String, ItemSupported> for O(1) lookups.

Suggested implementation:

                .getConnection();

        if (conn.getResponseCode() != 200) {
            throw new UnsupportedOperationException("Can't connect when sid is invalid");
        }
    }

    private static final Map<String, ItemSupported> ITEM_MAP;

    static {
        ITEM_MAP = Arrays.stream(ItemSupported.values())
                .collect(Collectors.toMap(
                    ItemSupported::getId,
                    item -> item
                ));
    }

    private ItemSupported getItemById(String id) {
        return ITEM_MAP.get(id);
    }

You'll need to add these imports if not already present:

  • import java.util.Map;
  • import java.util.Arrays;
  • import java.util.stream.Collectors;

check(this.config.item5);
}

private void check(BuyItem itemConfig) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider extracting the purchase logic in the check() method into a separate tryPurchaseItem() method to improve readability and reduce nesting.

The check() method mixes purchase validation with execution logic. Extract the purchase-related code into a dedicated method to reduce nesting and improve readability:

private void check(BuyItem itemConfig) {
    if (!itemConfig.enable || itemConfig.nextCheck > System.currentTimeMillis() 
            || itemConfig.quantity <= 0) {
        return;
    }

    updateCheckTime(itemConfig);

    if (itemConfig.itemToBuy != null && checkNormalCondition(itemConfig)
            && checkQuantityCondition(itemConfig.quantityCondition)) {
        tryPurchaseItem(itemConfig);
    }
}

private void tryPurchaseItem(BuyItem itemConfig) {
    ItemSupported itemSelected = getItemById(itemConfig.itemToBuy);
    if (itemSelected == null) return;

    if (this.stats.getTotalCredits() < itemSelected.getCreditsPrice() * itemConfig.quantity) {
        updateLabel(itemConfig, State.NO_CREDITS);
        return;
    }
    if (this.stats.getTotalUridium() < itemSelected.getUridiumPrice() * itemConfig.quantity) {
        updateLabel(itemConfig, State.NO_URI);
        return;
    }

    try {
        buyItem(itemSelected, itemConfig.quantity);
        updateLabel(itemConfig, State.PURCHASE_SUCCESS);
    } catch (Exception e) {
        updateLabel(itemConfig, State.PURCHASE_ERROR);
        e.printStackTrace();
    }
}


@Override
public void onTickTask() {
if (!this.backpage.isInstanceValid() || !this.backpage.getSidStatus().contains("OK")) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (review_instructions): Consider using early return to reduce nesting and improve readability.

Using early return can help in reducing the nesting level of the code, making it more readable and maintainable.

Review instructions:

Path patterns: *.java

Instructions:
It is a plugin for the darkbot bot in java, check that the code is clean and efficient.

return;
}

if (itemConfig.quantity <= 0) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (review_instructions): Consider using early return to reduce nesting and improve readability.

Using early return can help in reducing the nesting level of the code, making it more readable and maintainable.

Review instructions:

Path patterns: *.java

Instructions:
It is a plugin for the darkbot bot in java, check that the code is clean and efficient.


ItemSupported itemSelected = getItemById(itemConfig.itemToBuy);

if (itemSelected == null) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (review_instructions): Consider using early return to reduce nesting and improve readability.

Using early return can help in reducing the nesting level of the code, making it more readable and maintainable.

Review instructions:

Path patterns: *.java

Instructions:
It is a plugin for the darkbot bot in java, check that the code is clean and efficient.

return;
}

if (this.stats.getTotalCredits() < itemSelected.getCreditsPrice() * itemConfig.quantity) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (review_instructions): Consider using early return to reduce nesting and improve readability.

Using early return can help in reducing the nesting level of the code, making it more readable and maintainable.

Review instructions:

Path patterns: *.java

Instructions:
It is a plugin for the darkbot bot in java, check that the code is clean and efficient.

return;
}

if (this.stats.getTotalUridium() < itemSelected.getUridiumPrice() * itemConfig.quantity) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (review_instructions): Consider using early return to reduce nesting and improve readability.

Using early return can help in reducing the nesting level of the code, making it more readable and maintainable.

Review instructions:

Path patterns: *.java

Instructions:
It is a plugin for the darkbot bot in java, check that the code is clean and efficient.

updateLabel(itemConfig, State.PURCHASE_SUCCESS);
} catch (Exception e) {
updateLabel(itemConfig, State.PURCHASE_ERROR);
e.printStackTrace();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (review_instructions): Avoid using printStackTrace; consider logging the exception instead.

Using a logging framework instead of printStackTrace allows for better control over logging levels and outputs.

Review instructions:

Path patterns: *.java

Instructions:
It is a plugin for the darkbot bot in java, check that the code is clean and efficient.

dm94 added 3 commits January 31, 2025 16:58
@dm94 dm94 merged commit 5e6b49a into master Jan 31, 2025
6 checks passed
@dm94 dm94 deleted the feat/autoshop-task branch January 31, 2025 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant