mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-13 07:04:53 +09:00
Merge pull request #703 from clusterio/feature/connect-to-server
Add connect to server button to web UI using steam launch api
This commit is contained in:
4 files changed
+37
-23
No files matched your search
@@ -236,7 +236,7 @@ After completing the installation start up the controller and at least one host
|
||||
The installer provides the `run-controller` and `run-host` scripts to make this simple.
|
||||
Once the controller process is running you can log into the web interface which is hosted by default on http://localhost:8080/ (adjust the port number if you changed it), use the admin authentication token provided from the installation to log in.
|
||||
|
||||
The basics of setting up a Factorio server from the web interface is to create an instance, assign it to a host and then click start.
|
||||
The basics of setting up a Factorio server from the web interface is to create an instance, assign it to a host and then click start. You can also use the "Connect via Steam" button to launch Factorio directly and connect to the server using Steam's protocol handler.
|
||||
|
||||
### Running via Systemd
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { message, Button, Space, Table, Typography } from "antd";
|
||||
import { message, Button, Table } from "antd";
|
||||
import CopyOutlined from "@ant-design/icons/CopyOutlined";
|
||||
import type { SizeType } from "antd/es/config-provider/SizeContext";
|
||||
import type { ColumnsType } from "antd/es/table";
|
||||
@@ -9,13 +9,14 @@ import { useAccount } from "../model/account";
|
||||
import { useHosts } from "../model/host";
|
||||
import InstanceStatusTag from "./InstanceStatusTag";
|
||||
import StartStopInstanceButton from "./StartStopInstanceButton";
|
||||
import { InstanceDetails, integerFactorioVersion } from "@clusterio/lib";
|
||||
import * as lib from "@clusterio/lib";
|
||||
import Link from "./Link";
|
||||
import { instancePublicAddress } from "../util/instance";
|
||||
|
||||
const strcmp = new Intl.Collator(undefined, { numeric: true, sensitivity: "base" }).compare;
|
||||
|
||||
type InstanceListProps = {
|
||||
instances: ReadonlyMap<number, Readonly<InstanceDetails>>;
|
||||
instances: ReadonlyMap<number, Readonly<lib.InstanceDetails>>;
|
||||
size?: SizeType;
|
||||
hideAssignedHost?: boolean;
|
||||
};
|
||||
@@ -32,28 +33,14 @@ export default function InstanceList(props: InstanceListProps) {
|
||||
return hosts.get(hostId)?.name ?? String(hostId);
|
||||
}
|
||||
|
||||
function instancePublicAddress(instance: InstanceDetails) {
|
||||
if (instance.assignedHost === undefined) {
|
||||
return "";
|
||||
}
|
||||
let host = hosts.get(instance.assignedHost);
|
||||
if (!host || !host.publicAddress) {
|
||||
return "";
|
||||
}
|
||||
if (instance.gamePort === undefined) {
|
||||
return host.publicAddress;
|
||||
}
|
||||
return `${host.publicAddress}:${instance.gamePort}`;
|
||||
}
|
||||
|
||||
function integerFactorioVersionOrDefault(instance: InstanceDetails) {
|
||||
function integerFactorioVersionOrDefault(instance: lib.InstanceDetails) {
|
||||
if (instance.factorioVersion === undefined) {
|
||||
return -1;
|
||||
}
|
||||
return integerFactorioVersion(instance.factorioVersion);
|
||||
return lib.integerFactorioVersion(instance.factorioVersion);
|
||||
}
|
||||
|
||||
let columns: ColumnsType<InstanceDetails> = [
|
||||
let columns: ColumnsType<lib.InstanceDetails> = [
|
||||
{
|
||||
title: "Name",
|
||||
dataIndex: "name",
|
||||
@@ -76,7 +63,7 @@ export default function InstanceList(props: InstanceListProps) {
|
||||
title: "Public address",
|
||||
key: "publicAddress",
|
||||
render: (_, instance) => {
|
||||
let publicAddress = instancePublicAddress(instance);
|
||||
let publicAddress = instancePublicAddress(instance, hosts.get(instance.assignedHost!) ?? null);
|
||||
return publicAddress ? <>
|
||||
{publicAddress}
|
||||
<Button
|
||||
@@ -90,7 +77,10 @@ export default function InstanceList(props: InstanceListProps) {
|
||||
/>
|
||||
</> : "";
|
||||
},
|
||||
sorter: (a, b) => strcmp(instancePublicAddress(a), instancePublicAddress(b)),
|
||||
sorter: (a, b) => strcmp(
|
||||
instancePublicAddress(a, hosts.get(a.assignedHost!) ?? null),
|
||||
instancePublicAddress(b, hosts.get(b.assignedHost!) ?? null)
|
||||
),
|
||||
responsive: ["lg"],
|
||||
},
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@ import { useInstance } from "../model/instance";
|
||||
import { useHost } from "../model/host";
|
||||
import InstanceStatusTag from "./InstanceStatusTag";
|
||||
import Link from "./Link";
|
||||
import { instancePublicAddress } from "../util/instance";
|
||||
|
||||
type MenuItem = Required<MenuProps>["items"][number];
|
||||
const { Title } = Typography;
|
||||
@@ -73,6 +74,7 @@ function InstanceButtons(props: { instance: lib.InstanceDetails }) {
|
||||
let [exportingData, setExportingData] = useState(false);
|
||||
let instance = props.instance;
|
||||
let instanceId = instance.id!;
|
||||
let [host] = useHost(instance.assignedHost);
|
||||
|
||||
let instanceButtonMenuItems: MenuItem[] = [];
|
||||
if (account.hasPermission("core.instance.export_data")) {
|
||||
@@ -156,6 +158,17 @@ function InstanceButtons(props: { instance: lib.InstanceDetails }) {
|
||||
account.hasAnyPermission("core.instance.start", "core.instance.stop")
|
||||
&& <StartStopInstanceButton instance={instance} />
|
||||
}
|
||||
<Button
|
||||
onClick={() => {
|
||||
const address = instancePublicAddress(instance, host);
|
||||
if (address) {
|
||||
window.location.href = `steam://run/427520//--mp-connect=${address}`;
|
||||
}
|
||||
}}
|
||||
disabled={instance.status !== "running" || !instancePublicAddress(instance, host)}
|
||||
>
|
||||
Connect via Steam
|
||||
</Button>
|
||||
{account.hasPermission("core.instance.load_scenario") && <LoadScenarioModal instance={instance} />}
|
||||
{account.hasAnyPermission(
|
||||
"core.instance.export_data",
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import * as lib from "@clusterio/lib";
|
||||
|
||||
export function instancePublicAddress(instance: lib.InstanceDetails, host?: lib.HostDetails | null) {
|
||||
if (instance.assignedHost === undefined || !host || !host.publicAddress) {
|
||||
return "";
|
||||
}
|
||||
if (instance.gamePort === undefined) {
|
||||
return host.publicAddress;
|
||||
}
|
||||
return `${host.publicAddress}:${instance.gamePort}`;
|
||||
}
|
||||
Reference in new issue
Block a user