EU-Utility/CONTRIBUTING.md

571 lines
11 KiB
Markdown

# Contributing to EU-Utility
First off, thank you for considering contributing to EU-Utility! It's people like you that make this tool better for the entire Entropia Universe community.
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [Getting Started](#getting-started)
- [How Can I Contribute?](#how-can-i-contribute)
- [Development Setup](#development-setup)
- [Plugin Development](#plugin-development)
- [Style Guidelines](#style-guidelines)
- [Commit Messages](#commit-messages)
- [Pull Request Process](#pull-request-process)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Community](#community)
---
## Code of Conduct
This project and everyone participating in it is governed by our commitment to:
- **Be respectful** - Treat everyone with respect. Healthy debate is encouraged, but harassment is not tolerated.
- **Be constructive** - Provide constructive feedback and be open to receiving it.
- **Be inclusive** - Welcome newcomers and help them get started.
- **Focus on what's best** - Consider what is best for the community and the project.
---
## Getting Started
### Prerequisites
- Python 3.11 or higher
- Git
- A GitHub account
- Entropia Universe (for testing game integration features)
### Quick Setup
```bash
# 1. Fork the repository on GitHub
# 2. Clone your fork
git clone https://github.com/YOUR_USERNAME/EU-Utility.git
cd EU-Utility
# 3. Add upstream remote
git remote add upstream https://github.com/ImpulsiveFPS/EU-Utility.git
# 4. Create virtual environment
python -m venv venv
# 5. Activate it
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate
# 6. Install dependencies
pip install -r requirements.txt
# 7. Run tests
python -m pytest
# 8. Start EU-Utility
python -m core.main
```
---
## How Can I Contribute?
### 🐛 Report Bugs
Before creating a bug report, please check the [existing issues](https://github.com/ImpulsiveFPS/EU-Utility/issues) to avoid duplicates.
When creating a bug report, include:
- **Clear title** - Summarize the issue
- **Steps to reproduce** - Detailed steps to recreate the bug
- **Expected behavior** - What should have happened
- **Actual behavior** - What actually happened
- **Screenshots** - If applicable
- **System info:**
- OS and version
- Python version
- EU-Utility version
- Error messages/logs
### 💡 Suggest Enhancements
Enhancement suggestions are welcome! Please provide:
- **Clear description** - What would you like to see?
- **Use case** - Why would this be useful?
- **Proposed implementation** - How could it work? (optional)
### 🔌 Create Plugins
Plugins are the heart of EU-Utility! Create and share your own:
- Check the [Plugin Development Guide](./docs/PLUGIN_DEVELOPMENT_GUIDE.md)
- Submit to the Plugin Store
- Share on community forums
### 📝 Improve Documentation
Documentation improvements are always welcome:
- Fix typos and grammar
- Add examples and clarifications
- Translate to other languages
- Update outdated information
### 🧪 Write Tests
Help improve code quality by adding tests:
- Unit tests for core functionality
- Integration tests for plugins
- Performance benchmarks
### 🔧 Fix Issues
Look for issues labeled:
- `good first issue` - Great for newcomers
- `help wanted` - Extra attention needed
- `bug` - Something isn't working
- `enhancement` - New features
---
## Development Setup
### Project Structure
```
EU-Utility/
├── core/ # Core services
│ ├── main.py # Application entry point
│ ├── plugin_manager.py # Plugin management
│ ├── event_bus.py # Event system
│ ├── nexus_api.py # Nexus integration
│ └── ...
├── plugins/ # Plugin directory
│ ├── base_plugin.py # Base plugin class
│ ├── dashboard/ # Dashboard plugin
│ ├── loot_tracker/ # Loot tracker plugin
│ └── ...
├── docs/ # Documentation
├── tests/ # Test suite
├── data/ # User data (not in repo)
└── assets/ # Images, icons, sounds
```
### Development Workflow
```bash
# 1. Sync with upstream
git fetch upstream
git checkout main
git merge upstream/main
# 2. Create feature branch
git checkout -b feature/my-feature
# 3. Make changes
# ... edit files ...
# 4. Test changes
python -m pytest
python -m core.main
# 5. Commit changes
git add .
git commit -m "feat: add my feature"
# 6. Push to fork
git push origin feature/my-feature
# 7. Create Pull Request on GitHub
```
---
## Plugin Development
### Creating a New Plugin
1. **Create plugin directory:**
```bash
mkdir plugins/my_plugin
touch plugins/my_plugin/__init__.py
touch plugins/my_plugin/plugin.py
```
2. **Implement the plugin:**
```python
# plugins/my_plugin/plugin.py
from plugins.base_plugin import BasePlugin
class MyPlugin(BasePlugin):
name = "My Plugin"
version = "1.0.0"
author = "Your Name"
description = "What it does"
def initialize(self):
pass
def get_ui(self):
# Return QWidget
pass
```
3. **Test thoroughly:**
- Test UI rendering
- Test hotkey functionality
- Test data persistence
- Test error handling
4. **Add documentation:**
- Plugin README.md
- Code comments
- Usage examples
### Plugin Guidelines
**Do:**
- Use existing core services
- Follow naming conventions
- Add proper error handling
- Clean up resources in `shutdown()`
- Use background tasks for heavy operations
- Follow the style guide
**Don't:**
- Block the main thread
- Access game files directly
- Hardcode paths
- Ignore errors silently
- Duplicate existing functionality
---
## Style Guidelines
### Python Code Style
We follow [PEP 8](https://www.python.org/dev/peps/pep-0008/) with some additions:
```python
"""
EU-Utility - Module Name
Short description of the module.
Features:
- Feature 1
- Feature 2
"""
from typing import Optional, Dict, Any, List
from dataclasses import dataclass
# Constants
MAX_RETRIES = 3
DEFAULT_TIMEOUT = 30
@dataclass
class Config:
"""Configuration data class."""
name: str
value: int
enabled: bool = True
class MyClass:
"""
Brief description of the class.
Longer description with usage examples.
Attributes:
name: The name attribute
value: The value attribute
Example:
>>> obj = MyClass("test", 42)
>>> obj.process()
"""
def __init__(self, name: str, value: int) -> None:
"""Initialize the class."""
self.name = name
self.value = value
self._private_var = None
def process(self, data: Dict[str, Any]) -> Optional[str]:
"""
Process the data.
Args:
data: Input data dictionary
Returns:
Processed string or None if invalid
Raises:
ValueError: If data is invalid
"""
if not data:
raise ValueError("Data cannot be empty")
return f"{self.name}: {self.value}"
```
### UI Style Guide
Use the EU-Utility theme:
```python
# Colors
BG_DARK = "#1a1a1a" # Main background
BG_PANEL = "#2a2a2a" # Panel background
ACCENT_ORANGE = "#ff8c42" # Accent color
TEXT_WHITE = "#ffffff" # Primary text
TEXT_MUTED = "rgba(255,255,255,150)" # Secondary text
# Apply to widgets
widget.setStyleSheet(f"""
QWidget {{
background-color: {BG_DARK};
color: {TEXT_WHITE};
}}
""")
```
### Documentation Style
- Use clear, concise language
- Include code examples
- Document all public methods
- Use type hints
- Keep line length under 100 characters
---
## Commit Messages
We follow [Conventional Commits](https://www.conventionalcommits.org/):
```
<type>(<scope>): <subject>
<body>
<footer>
```
### Types
- **feat** - New feature
- **fix** - Bug fix
- **docs** - Documentation only
- **style** - Code style (formatting, no logic change)
- **refactor** - Code refactoring
- **perf** - Performance improvements
- **test** - Adding tests
- **chore** - Maintenance tasks
### Examples
```
feat(plugins): add auction tracker plugin
Add new plugin for tracking auction prices and markups.
Features:
- Real-time price tracking
- Historical data charts
- Markup calculations
Closes #123
```
```
fix(ocr): resolve memory leak in capture method
The OCR service was not releasing image buffers,
causing memory usage to grow over time.
Fixes #456
```
```
docs(readme): update installation instructions
Add Windows 11 specific steps and troubleshoot
tips for common installation issues.
```
---
## Pull Request Process
1. **Update documentation** - Update README.md, CHANGELOG.md, or docs/ if needed
2. **Add tests** - Include tests for new functionality
3. **Update CHANGELOG.md** - Add your changes under the `[Unreleased]` section
4. **Ensure tests pass** - Run `python -m pytest`
5. **Fill out PR template** - Describe what and why
6. **Request review** - Wait for maintainer review
7. **Address feedback** - Make requested changes
8. **Merge** - Maintainers will merge when ready
### PR Checklist
- [ ] Code follows style guidelines
- [ ] Tests pass locally
- [ ] Documentation updated
- [ ] CHANGELOG.md updated
- [ ] Commit messages follow conventions
- [ ] PR description is clear
---
## Reporting Bugs
### Before Submitting
- Check existing issues
- Try the latest version
- Check [TROUBLESHOOTING.md](./docs/TROUBLESHOOTING.md)
### Bug Report Template
```markdown
**Description**
Clear description of the bug.
**To Reproduce**
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected Behavior**
What should have happened.
**Screenshots**
If applicable, add screenshots.
**Environment:**
- OS: [e.g., Windows 11]
- Python: [e.g., 3.11.4]
- EU-Utility: [e.g., 2.0.0]
**Logs:**
```
Paste relevant log output
```
**Additional Context**
Any other information.
```
---
## Suggesting Enhancements
### Enhancement Template
```markdown
**Feature Request**
Clear description of the feature.
**Problem/Motivation**
What problem does this solve?
**Proposed Solution**
How should it work?
**Alternatives**
Other approaches considered.
**Additional Context**
Mockups, examples, etc.
```
---
## Community
### Communication Channels
- **GitHub Issues** - Bug reports and feature requests
- **GitHub Discussions** - General discussion and Q&A
- **Discord** - Real-time chat (link TBD)
### Recognition
Contributors will be:
- Listed in CONTRIBUTORS.md
- Mentioned in release notes
- Credited in relevant documentation
---
## Development Tips
### Debugging
```python
# Enable debug logging
import logging
logging.basicConfig(level=logging.DEBUG)
# Add to your plugin
self.log_debug("Debug information")
```
### Testing Plugins
```python
# tests/test_my_plugin.py
import pytest
from plugins.my_plugin.plugin import MyPlugin
class TestMyPlugin:
def test_initialization(self):
plugin = MyPlugin()
plugin.initialize()
assert plugin.name == "My Plugin"
```
### Profiling
```python
# Profile plugin performance
import cProfile
import pstats
profiler = cProfile.Profile()
profiler.enable()
# Your code here
profiler.disable()
stats = pstats.Stats(profiler)
stats.sort_stats('cumtime')
stats.print_stats(20)
```
---
## Questions?
If you have questions:
1. Check the [documentation](./docs/)
2. Search existing issues
3. Ask in GitHub Discussions
4. Join our Discord
---
Thank you for contributing to EU-Utility! 🎮✨