Skip to content

Commit

Permalink
Merge branch 'main' into patch-2
Browse files Browse the repository at this point in the history
  • Loading branch information
CosmicFusion authored Aug 8, 2023
2 parents 6b9894e + d8e142d commit e2fcef8
Show file tree
Hide file tree
Showing 72 changed files with 465 additions and 364 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ packagecache
/repo/
/flatpak/
.vscode/*
/.vscode/*

/build-flatpak.sh
2 changes: 2 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ If all apply, then please consider opening a [new issue](https://github.com/bott
## Want to Submit Code?
You can submit code by [forking](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/about-forks) this project, editing the desired code and finally submitting a [pull request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).

To build Bottles, refer to the [Building](README.md#Building) instructions.

### Having Trouble Understanding the Source Code?
If you want to inquire to understand the code base, you can contact us via [Discord](https://discord.com/invite/wF4JAdYrTR). We'd love to help you out!

Expand Down
99 changes: 36 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
<div align="center">
<img src="https://raw.githubusercontent.com/bottlesdevs/Bottles/main/data/icons/hicolor/scalable/apps/com.usebottles.bottles.svg" width="64">
<h1 align="center">Bottles</h1>
<p align="center">Easily run Windows Software using Bottles</p>
<p align="center">Run Windows Software on Linux</p>
</div>

<br/>

<div align="center">
<a href="https://flathub.org/apps/com.usebottles.bottles">
<img alt="Flathub" src="https://img.shields.io/flathub/downloads/com.usebottles.bottles" />
</a>
<a href="https://hosted.weblate.org/engage/bottles">
<img src="https://hosted.weblate.org/widgets/bottles/-/bottles/svg-badge.svg" />
</a>
Expand All @@ -16,10 +19,10 @@
<a href="https://github.com/bottlesdevs/Bottles/blob/main/LICENSE">
<img src="https://img.shields.io/badge/License-GPL--3.0-blue.svg">
</a>
<br>
<a href="https://github.com/bottlesdevs/Bottles/actions">
<img src="https://github.com/bottlesdevs/Bottles/workflows/Build%20release%20packages/badge.svg">
</a>
<br>
<a href="https://stopthemingmy.app" title="Please do not theme this app">
<img src="https://stopthemingmy.app/badge.svg">
</a>
Expand All @@ -36,69 +39,39 @@

![Bottles Dark](docs/screenshot-dark.png#gh-dark-mode-only)![Bottles Light](docs/screenshot-light.png#gh-light-mode-only)

## 📚 Documentation
Before opening a new issue, check if the topic has already been covered
in our [documentation](https://docs.usebottles.com).

Please note that some pages of the documentation are still being written.

## 🗣 Help Bottles speak your language
Read [here](po#readme) how to translate Bottles to your language or how to help
improve existing ones.

## 🦾 Features
- Create bottles based on environments (a set of rules and dependencies)
- Access to a customizable environment for all your experiments
- Automated installers
- Run every executable (.exe/.msi/.bat) in your bottles, using the context menu in your file manager
- Integrated management and storage for executable file arguments
- Support for custom environment variables
- Simplified DLL overrides
- Manage and install multiple wine/proton/dxvk versions and on-the-fly change
- Various optimizations for better gaming performance (esync, fsync, dxvk, cache, shader compiler, offload ... and much more.)
- Tweak different wine prefix settings, without leaving Bottles
- Automated dxvk installation
- System for checking runner updates for the bottle and automatic repair in case of breakage
- Integrated Dependencies installer with compatibility check based on a community-driven [repository](https://github.com/bottlesdevs/dependencies)
- Detection of installed programs
- Integrated Task manager for wine processes
- Easy access to ProtonDB and WineHQ for support
- Configurations update system across Bottles versions
- Backup and Import bottles from older version and from other managers (Lutris, POL, ..)
- Bottles versioning
- ... and much more that you can find by installing Bottles!

### 🚧 Work in progress
- Layers (dependencies and programs on different layers) [#510](https://github.com/bottlesdevs/Bottles/issues/510)

## ↗️ Install
Bottles is officially provided as [Flatpak](https://flathub.org/apps/details/com.usebottles.bottles).

Read [here](https://docs.usebottles.com/getting-started/installation) how to
install Bottles on your distribution.

### Notices for package maintainers
We are happy to see packaged Bottles but we ask you to respect some small rules:
- The package must be `bottles`. In other distributions it is possible to use suffixes (e.g. `bottles-git` on Arch Linux for the git based package) while on others the RDNN format is required (e.g. `com.usebottles.bottles` on elementary OS and Flathub repository). All other nomenclatures are discouraged.
- Do not package external files and do not make changes to the code, no hard script. Obviously with the exception of files essential for packaging.
- Package version should follow the CalVer model (year.month.day) and the release cycle of the project. Bottles has 2 releases per month: one on 14th and one on 28th. When a hotfix is released, this will be appended to the release version (e.g. 2022.2.14-1). Bottles has a codename too which is not mandatory and currently only used by the Flatpak.

## Shortcuts
| Shortcut | Action |
|:--------:|:-----------------------:|
| `Ctrl+Q` | Close Bottles |
| `Ctrl+R` | Reload the Bottles list |
| `F1` | Go to the documentation |
| `Esc` | Go back |

## FAQ
- [Why Bottles?](https://docs.usebottles.com/faq/why-bottles)
- [Where is Winetricks?](https://docs.usebottles.com/faq/where-is-winetricks)
- [Older versions will be deprecated?](https://docs.usebottles.com/faq/updates-and-old-versions#older-versions-will-be-deprecated)
- [Backward compatibility?](https://docs.usebottles.com/faq/updates-and-old-versions#backward-compatibility)
## Installation

<a href='https://flathub.org/apps/com.usebottles.bottles'><img width='240' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-en.png'/></a>

## Contributing

Refer to the [Contributing](CONTRIBUTING.md) page.

## Building

⚠️ Be sure to backup all your data before testing experimental builds of Bottles!

There are two methods to build Bottles. The first and longer method is using `org.flatpak.Builder`, and the second but shorter method is building directly.

### org.flatpak.Builder

1. Install [`org.flatpak.Builder`](https://github.com/flathub/org.flatpak.Builder) from Flathub
1. Clone `https://github.com/bottlesdevs/Bottles.git` (or your fork)
1. Run `flatpak run org.flatpak.Builder --install --install-deps-from=flathub --default-branch=master --force-clean build-dir com.usebottles.bottles.yml` in the terminal from the root of the repository (use `--user` if necessary)
1. Run `flatpak run com.usebottles.bottles//master` to launch it

### Meson

Since Bottles is primarily and officially distributed as a Flatpak, we only provide instructions to directly build it inside a Flatpak environment:

1. Download and install the latest build of Bottles: [bottles-x86_64.zip](https://nightly.link/bottlesdevs/Bottles/workflows/build_flatpak/main/bottles-x86_64.zip). Unzip it, and run `flatpak install bottles.flatpak` (use `--user` if necessary)
2. Run `flatpak run -d --filesystem=$PWD --command=bash com.usebottles.bottles//master` from the root of the repository, followed by `./utils/install.sh`. This will build Bottles and install it under the `build/` directory.
3. Run `./build/bin/bottles` to launch Bottles

Due to GNOME Builder limitations, Builder cannot build Bottles for the time being; see [GNOME/gnome-builder#2061](https://gitlab.gnome.org/GNOME/gnome-builder/-/issues/2061) for more context. This is the best workaround we can provide.

## Code of Conduct
This project follows the [GNOME Code of Conduct.](https://wiki.gnome.org/Foundation/CodeOfConduct) You are expected to follow it in all Bottles spaces, such as this repository, project's social media, messenger chats and forums. Bigotry and harassment will not be tolerated.
This project follows the [GNOME Code of Conduct](https://wiki.gnome.org/Foundation/CodeOfConduct). You are expected to follow it in all Bottles spaces, such as this repository, the project's social media, messenger chats and forums. Bigotry and harassment will not be tolerated.

## Sponsors
<a href="https://www.jetbrains.com/?from=bottles"><img height="55" src="https://unifiedban.solutions/static/images/jetbrains-logos/jetbrains.png" /></a>&nbsp;&nbsp;&nbsp;
Expand Down
1 change: 0 additions & 1 deletion bottles/backend/cabextract.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import shlex
import shutil
import subprocess
from gettext import gettext as _
from typing import Optional

from bottles.backend.logger import Logger
Expand Down
3 changes: 0 additions & 3 deletions bottles/backend/dlls/dll.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

import os
import shutil
from glob import glob
from typing import NewType, Optional
from abc import abstractmethod
from copy import deepcopy

Expand All @@ -27,7 +25,6 @@
from bottles.backend.models.enum import Arch
from bottles.backend.utils.manager import ManagerUtils
from bottles.backend.wine.reg import Reg
from bottles.backend.wine.wineboot import WineBoot

logging = Logger()

Expand Down
1 change: 0 additions & 1 deletion bottles/backend/managers/importer.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@
import os

from bottles.backend.models.config import BottleConfig
from bottles.backend.utils import yaml
import subprocess
from glob import glob
from datetime import datetime
Expand Down
118 changes: 79 additions & 39 deletions bottles/backend/managers/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
from bottles.backend.utils.lnk import LnkUtils
from bottles.backend.utils.manager import ManagerUtils
from bottles.backend.utils.singleton import Singleton
from bottles.backend.utils.steam import SteamUtils
from bottles.backend.utils.threading import RunAsync
from bottles.backend.wine.reg import Reg
from bottles.backend.wine.regkeys import RegKeys
Expand Down Expand Up @@ -346,7 +347,7 @@ def check_runners(self, install_latest: bool = True) -> bool:

# lock winemenubuilder.exe
for runner in runners:
if runner not in self.supported_proton_runners:
if not SteamUtils.is_proton(runner):
winemenubuilder_paths = [
f"{runner}lib64/wine/x86_64-windows/winemenubuilder.exe",
f"{runner}lib/wine/x86_64-windows/winemenubuilder.exe",
Expand Down Expand Up @@ -376,7 +377,7 @@ def check_runners(self, install_latest: bool = True) -> bool:
_runner = os.path.basename(os.path.normpath(runner))
runners_available.append(_runner)

runners_available = sorted(runners_available, reverse=True)
runners_available = self.__sort_runners(runners_available, "")

runners_order = {
"soda": [],
Expand Down Expand Up @@ -506,6 +507,57 @@ def check_latencyflex(self, install_latest: bool = True) -> bool:
self.latencyflex_available = res
return res is not False

def get_offline_components(self, component_type: str, extra_name_check: str = "") -> list:
components = {
"dxvk": {
"available": self.dxvk_available,
"supported": self.supported_dxvk,
},
"vkd3d": {
"available": self.vkd3d_available,
"supported": self.supported_vkd3d,
},
"nvapi": {
"available": self.nvapi_available,
"supported": self.supported_nvapi,
},
"latencyflex": {
"available": self.latencyflex_available,
"supported": self.supported_latencyflex,
},
"runner": {
"available": self.runners_available,
"supported": self.supported_wine_runners,
},
"runner:proton": {
"available": self.runners_available,
"supported": self.supported_proton_runners,
}
}
if component_type not in components:
logging.warning(f"Unknown component type found: {component_type}")
raise ValueError("Component type not supported.")

component_list = components[component_type]
offline_components = list(set(component_list["available"]).difference(component_list["supported"].keys()))

if component_type == "runner":
offline_components = [ runner for runner in offline_components \
if not runner.startswith("sys-") and \
not SteamUtils.is_proton(ManagerUtils.get_runner_path(runner)) ]
elif component_type == "runner:proton":
offline_components = [ runner for runner in offline_components \
if SteamUtils.is_proton(ManagerUtils.get_runner_path(runner)) ]

if extra_name_check and extra_name_check not in component_list["available"] \
and extra_name_check not in component_list["supported"]:
offline_components.append(extra_name_check)

try:
return sort_by_version(offline_components)
except ValueError:
return sorted(offline_components, reverse=True)

def __check_component(self, component_type: str, install_latest: bool = True) -> Union[bool, list]:
components = {
"dxvk": {
Expand Down Expand Up @@ -943,37 +995,28 @@ def create_bottle_from_config(self, config: BottleConfig) -> bool:
to latest Soda. If there is no Soda, set it to the
first one.
'''
config.Runner = self.get_latest_runner("wine")
config.Runner = self.get_latest_runner()

if config.DXVK not in self.dxvk_available:
'''
If the DXVK is not in the list of available DXVKs, set it to
highest version.
highest version which is the first in the list.
'''
config.DXVK = sorted(
[dxvk for dxvk in self.dxvk_available],
key=lambda x: x.split("-")[-1]
)[-1]
config.DXVK = self.dxvk_available[0]

if config.VKD3D not in self.vkd3d_available:
'''
If the VKD3D is not in the list of available VKD3Ds, set it to
highest version.
highest version which is the first in the list.
'''
config.VKD3D = sorted(
[vkd3d for vkd3d in self.vkd3d_available],
key=lambda x: x.split("-")[-1]
)[-1]
config.VKD3D = self.vkd3d_available[0]

if config.NVAPI not in self.nvapi_available:
'''
If the NVAPI is not in the list of available NVAPIs, set it to
highest version.
highest version which is the first in the list.
'''
config.NVAPI = sorted(
[nvapi for nvapi in self.nvapi_available],
key=lambda x: x.split("-")[-1]
)[-1]
config.NVAPI = self.nvapi_available[0]

# create the bottle path
bottle_path = os.path.join(Paths.bottles, config.Name)
Expand Down Expand Up @@ -1375,34 +1418,31 @@ def components_check():
data={"config": config}
)

def __sort_runners(self, prefix: str, fallback: bool = True) -> sorted:
@staticmethod
def __sort_runners(runner_list: list, prefix: str) -> sorted:
"""
Return a sorted list of runners for a given prefix. Fallback to the
first available if fallback argument is True.
"""
runners = sorted(
[
runner
for runner in self.runners_available
if runner.startswith(prefix)
],
key=lambda x: x.split("-")[1],
reverse=True
)
runners = [ runner for runner in runner_list if runner.startswith(prefix) ]

if len(runners) > 0:
return runners[0]
try:
runners = sort_by_version(runners, "")
except ValueError:
runners = sorted(
runners,
key=lambda x: x.split("-")[1],
reverse=True
)

return self.runners_available[0] if fallback else []
return runners

def get_latest_runner(self, runner_type: str = "wine") -> list:
"""Return the latest available runner for a given type."""
try:
if runner_type in ["", "wine"]:
return self.__sort_runners("soda")
return self.__sort_runners("proton")
except IndexError:
return []
def get_latest_runner(self, runner_prefix: str = "soda") -> list:
"""Return the latest available runner for a given prefix."""
runners = self.__sort_runners(self.runners_available, runner_prefix)
if not runners:
runners = self.__sort_runners(self.runners_available, "")
return runners[0] if runners else []

def delete_bottle(self, config: BottleConfig) -> bool:
"""
Expand Down
5 changes: 4 additions & 1 deletion bottles/backend/managers/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
#

import os
from pathlib import Path
from functools import lru_cache

from bottles.backend.globals import Paths
Expand Down Expand Up @@ -134,6 +133,10 @@ def __get_steam_runtime():
return available_runtimes

lookup = {
"sniper": {
"name": "sniper",
"entry_point": os.path.join(steam_manager.steam_path, "steamapps/common/SteamLinuxRuntime_sniper/_v2-entry-point"),
},
"soldier": {
"name": "soldier",
"entry_point": os.path.join(steam_manager.steam_path, "steamapps/common/SteamLinuxRuntime_soldier/_v2-entry-point"),
Expand Down
Loading

0 comments on commit e2fcef8

Please sign in to comment.