Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-node-insim

Package Overview
Dependencies
Maintainers
0
Versions
6
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-node-insim

React Node InSim

  • 0.0.6
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
3
Maintainers
0
Weekly downloads
 
Created
Source

React Node InSim

NPM Version

A React renderer for InSim buttons, based on Node InSim.

Introduction

🚧 This project is still under development. Any API may change as needed.

React Node InSim is a React renderer for Live for Speed InSim buttons. It also provides layout components for easier button positioning, hooks for handling incoming InSim packets and tracking server connections & players.

It is based on Node InSim, a Node.js library, written in TypeScript, for InSim communication.

It allows you to create things like this:

Live list of connections and players
Show source code
import type { InSim } from 'node-insim';
import { InSimFlags, IS_BTC, IS_MST, PacketType } from 'node-insim/packets';
import { StrictMode } from 'react';
import {
  Button,
  ConnectionsProvider,
  createRoot,
  PlayersProvider,
  useConnections,
  useOnConnect,
  useOnPacket,
  usePlayers,
  VStack,
} from 'react-node-insim';

function App() {
  // Get the list of current players and connections
  const players = usePlayers();
  const connections = useConnections();

  // Do something after the InSim app has been connected to LFS
  useOnConnect((packet, inSim) => {
    console.log(`Connected to LFS ${packet.Product} ${packet.Version}`);
    inSim.send(new IS_MST({ Msg: `React Node InSim connected` }));
  });

  // Handle incoming packets
  useOnPacket(PacketType.ISP_NCN, (packet) => {
    console.log(`New connection: ${packet.UName}`);
  });

  // Clickable buttons
  const handlePlayerClick = (plid: number) => (_: IS_BTC, inSim: InSim) => {
    inSim.send(new IS_MST({ Msg: `/echo PLID ${plid}` }));
  };

  const handleConnectionClick = (ucid: number) => (_: IS_BTC, inSim: InSim) => {
    inSim.send(new IS_MST({ Msg: `/echo UCID ${ucid}` }));
  };

  return (
    <>
      <Button top={10} left={40} width={30} height={5} UCID={255} color="title">
        Players
      </Button>
      <VStack
        background="dark"
        top={15}
        left={40}
        width={30}
        height={5}
        UCID={255}
      >
        {players.map((player) => (
          <Button key={player.PLID} onClick={handlePlayerClick(player.PLID)}>
            {player.PName}
          </Button>
        ))}
      </VStack>
      <Button top={10} left={70} width={30} height={5} UCID={255} color="title">
        Connections
      </Button>
      <VStack
        background="dark"
        top={15}
        left={70}
        width={30}
        height={5}
        UCID={255}
      >
        {connections.map((connection) => (
          <Button
            key={connection.UCID}
            onClick={handleConnectionClick(connection.UCID)}
          >
            {connection.UName}
          </Button>
        ))}
      </VStack>
    </>
  );
}

const root = createRoot({
  name: 'React InSim',
  host: '127.0.0.1',
  port: 29999,
  flags: InSimFlags.ISF_LOCAL,
});

root.render(
  <StrictMode>
    <PlayersProvider>
      <ConnectionsProvider>
        <App />
      </ConnectionsProvider>
    </PlayersProvider>
  </StrictMode>,
);

Table of contents

Requirements

Installation

NPM

npm install react@18 node-insim react-node-insim

Yarn

yarn add react@18 node-insim react-node-insim

pnpm

pnpm add react@18 node-insim react-node-insim

Basic usage

Displaying an InSim button on a local computer

import { InSimFlags } from 'node-insim/packets';
import { Button, createRoot } from 'react-node-insim';

const root = createRoot({
  name: 'React InSim',
  host: '127.0.0.1',
  port: 29999,
  flags: InSimFlags.ISF_LOCAL,
});

root.render(
  <Button top={100} left={80} width={30} height={10}>
    Hello InSim!
  </Button>,
);

You can use React hooks as usual to display stateful data via InSim.

Button showing current time
import { InSimFlags } from 'node-insim/packets';
import { useEffect, useState } from 'react';
import { Button, createRoot } from 'react-node-insim';

function App() {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const interval = setInterval(() => {
      setTime(new Date());
    }, 1000);

    return () => {
      clearInterval(interval);
    };
  });

  return (
    <Button top={100} left={80} width={40} height={10}>
      Current time: {time.toLocaleTimeString()}
    </Button>
  );
}

const root = createRoot({
  name: 'React InSim',
  host: '127.0.0.1',
  port: 29999,
  flags: InSimFlags.ISF_LOCAL,
});

root.render(<App />);

Button

The Button component is used to display a button in LFS.

  • Buttons are drawn on a 200 by 200 canvas using absolute positioning
  • The maximum number of rendered buttons on a screen is 240

Import

import { Button } from 'react-node-insim';

Usage

Button
<Button top={100} left={80} width={30} height={10}>
  Button
</Button>
Placement

Buttons use XY coordinates to position themselves on the screen. The top and left props control the button's X and Y position on the screen. The allowed range of values is 0 to 200.

Button placement
<>
  <Button width={12} height={6} top={100} left={40}>
    Button
  </Button>
  <Button width={12} height={6} top={100} left={53}>
    Button
  </Button>
  <Button width={12} height={6} top={106} left={40}>
    Button
  </Button>
  <Button width={12} height={6} top={106} left={53}>
    Button
  </Button>
</>
Sizes

Use the width and height props to change the dimensions of the button. The allowed range of values is 0 to 200.

Button sizes
<>
  <Button variant="light" top={100} left={40} width={6} height={4}>
    Button
  </Button>
  <Button variant="light" top={99} left={47} width={10} height={6}>
    Button
  </Button>
  <Button variant="light" top={97} left={58} width={14} height={10}>
    Button
  </Button>
</>
Variants

Use the variant prop to change the button's visual style. You can use light or dark. If you don't specify a variant, the button will have transparent background and a light gray text color.

Button variants
<>
  <Button top={100} left={40} width={12} height={6} variant="light">
    Button
  </Button>
  <Button top={100} left={53} width={12} height={6} variant="dark">
    Button
  </Button>
</>
Text colors

Use the color prop to customize the button's text color. If you don't specify a color, the button text will be default.

Button text colors
<>
  <Button top={73} left={40} width={12} height={6} color="default">
    default
  </Button>
  <Button top={73} left={53} width={12} height={6} color="title">
    title
  </Button>
  <Button top={73} left={66} width={12} height={6} color="unselected">
    unselected
  </Button>
  <Button top={73} left={79} width={12} height={6} color="selected">
    selected
  </Button>
  <Button top={80} left={40} width={12} height={6} color="ok">
    ok
  </Button>
  <Button top={80} left={53} width={12} height={6} color="cancel">
    cancel
  </Button>
  <Button top={80} left={66} width={12} height={6} color="textstring">
    textstring
  </Button>
  <Button top={80} left={79} width={12} height={6} color="unavailable">
    unavailable
  </Button>
</>

You can choose from a set of semantic colors or use one of the colors from the LFS color palette.

Semantic colors

  • default
  • title
  • unselected
  • selected
  • ok
  • cancel
  • textstring
  • unavailable

Note: The semantic color values can be customized in LFS Options -> Display -> Interface.

LFS color palette

  • black
  • red
  • green
  • yellow
  • blue
  • magenta
  • cyan
  • white
Background colors

Use the background prop to customize the button's background color. If you don't specify a color, the background will be transparent.

Button background colors
<>
  <Button top={67} left={40} width={12} height={6} background="light">
    light
  </Button>
  <Button top={67} left={53} width={12} height={6} background="dark">
    dark
  </Button>
  <Button top={67} left={66} width={12} height={6} background="transparent">
    transparent
  </Button>
</>

Horizontal stack

HStack displays buttons in a column without having to specify each button's position manually. You can also override button colors and sizes.

Import

import { HStack } from 'react-node-insim';

Usage

Horizontal stack
<HStack top={10} left={20} width={7} height={4} variant="dark">
  <Button>Stacked button</Button>
  <Button color="title">Custom color</Button>
  <Button height={6}>Custom height</Button>
</HStack>

Vertical stack

VStack displays buttons in a row without having to specify each button's position manually. You can also override button colors and sizes.

Import

import { VStack } from 'react-node-insim';

Usage

Vertical stack
<VStack top={10} left={20} width={7} height={4} variant="dark">
  <Button>Stacked button</Button>
  <Button color="title">Custom color</Button>
  <Button height={6}>Custom height</Button>
</VStack>

Flex

Flex layout displays buttons in a row or column with flexbox options.

Import

import { Flex } from 'react-node-insim';

Usage

Flex
<Flex
  top={10}
  left={20}
  width={36}
  height={16}
  alignItems="center"
  justifyContent="space-evenly"
  background="dark"
  backgroundColor="light"
>
  <Button width={8} height={4}>
    Left
  </Button>
  <Button width={10} height={6}>
    Center
  </Button>
  <Button width={8} height={4}>
    Right
  </Button>
</Flex>

Grid

Grid layout displays buttons in a grid.

Import

import { Grid, GridButton } from 'react-node-insim';

Usage

Grid
<Grid
  top={30}
  left={40}
  width={30}
  height={30}
  background="dark"
  backgroundColor="light"
  gridTemplateColumns="1fr 2fr 1fr"
  gridTemplateRows="1fr 3fr 2fr"
  gridColumnGap={1}
  gridRowGap={1}
>
  <GridButton>1</GridButton>
  <GridButton
    gridColumnStart={2}
    gridRowStart={1}
    gridRowEnd={3}
    color="title"
    background="light"
  >
    2
  </GridButton>
  <GridButton
    gridColumnStart={3}
    gridColumnEnd={3}
    gridRowStart={1}
    gridRowEnd={3}
  >
    3
  </GridButton>
  <GridButton alignSelf="end" height={10}>
    4
  </GridButton>
  <GridButton gridColumnStart={1} gridColumnEnd={4}>
    5
  </GridButton>
</Grid>

Toggle button

A button that can be toggled on and off by clicking it.

Import

import { ToggleButton } from 'react-node-insim';

Usage

Toggle button being toggled on and off
function App() {
  const [isOn, setIsOn] = useState(false);

  return (
    <ToggleButton
      top={100}
      left={80}
      width={12}
      height={6}
      isOn={isOn}
      onToggle={setIsOn}
    >
      Toggle
    </ToggleButton>
  );
}
Variants

Use the variant prop to change the button's background style. You can use light or dark. If you don't specify a variant, light will be used.

Toggle button variants
<>
  <ToggleButton variant="light" top={100} left={40} width={12} height={6}>
    Toggle
  </ToggleButton>
  <ToggleButton variant="dark" top={100} left={53} width={12} height={6}>
    Toggle
  </ToggleButton>
</>
Disabled state

Use the isDisabled prop to prevent toggling the button on/off.

Enabled and disabled toggle buttons
<>
  <ToggleButton
    isDisabled={false}
    variant="light"
    top={100}
    left={40}
    width={12}
    height={6}
  >
    Enabled
  </ToggleButton>
  <ToggleButton
    isDisabled
    variant="light"
    top={100}
    left={53}
    width={12}
    height={6}
  >
    Disabled
  </ToggleButton>
  <ToggleButton
    isDisabled={false}
    variant="dark"
    top={106}
    left={40}
    width={12}
    height={6}
  >
    Enabled
  </ToggleButton>
  <ToggleButton
    isDisabled
    variant="dark"
    top={106}
    left={53}
    width={12}
    height={6}
  >
    Disabled
  </ToggleButton>
</>

Toggle button group

A group of buttons that can be toggled on and off by clicking them.

Import

import { ToggleButtonGroup } from 'react-node-insim';

Usage

Toggle button group
const options = [
  { label: 'low', value: 1 },
  { label: 'medium', value: 2 },
  { label: 'high', value: 3 },
];

function App() {
  const [selectedOption, setSelectedOption] = useState(options[0]);

  return (
    <ToggleButtonGroup
      top={30}
      left={50}
      width={36}
      height={6}
      options={options}
      selectedOption={selectedOption}
      onChange={setSelectedOption}
    />
  );
}

Text box

A text box whose content can span multiple rows. If the content is too long, the text box will show a scrollbar.

Import

import { TextBox } from 'react-node-insim';

Usage

Text box
<TextBox
  top={40}
  left={50}
  cols={20}
  rows={4}
  width={20}
  rowHeight={4}
  variant="light"
>
  Hello world this is a text box lorem ipsum dolor sit amet consectetur
  adipisicing elitrea lorem ipsum dolor sit amet consectetur adipisicing elit
</TextBox>

Hooks

useOnConnect

Execute code after the InSim app has been connected.

The first parameter is an IS_VER packet callback executed when IS_VER is received upon successful InSim connection to LFS.

import { useOnConnect } from 'react-node-insim';

function App() {
  useOnConnect((packet, inSim) => {
    console.log(`Connected to LFS ${packet.Product} ${packet.Version}`);
    inSim.send(new IS_MST({ Msg: `React Node InSim connected` }));
  });

  return null;
}

useOnDisconnect

Execute code after the InSim app has been disconnected.

The first parameter is the "disconnect" event callback from Node InSim.

import { useOnDisconnect } from 'react-node-insim';

function App() {
  useOnDisconnect(() => {
    console.log('Disconnected from LFS');
  });

  return null;
}

useOnPacket

Execute code when an InSim packet is received

import { useOnPacket } from 'react-node-insim';

function App() {
  useOnPacket(PacketType.ISP_NCN, (packet) => {
    console.log(`New connection: ${packet.UName}`);
  });

  return null;
}

useConnections

Get a live list of all connected guests.

import { useConnections } from 'react-node-insim';

function App() {
  const connections = useConnections();

  return (
    <VStack background="dark" top={10} left={10} width={20} height={4}>
      {connections.map((connection) => (
        <Button key={connection.UCID}>{connection.UName}</Button>
      ))}
    </VStack>
  );
}

usePlayers

Get a live list of all players on track.

import { usePlayers } from 'react-node-insim';

function App() {
  const players = usePlayers();

  return (
    <VStack background="dark" top={10} left={10} width={20} height={4}>
      {players.map((player) => (
        <Button key={player.PLID}>{player.PName}</Button>
      ))}
    </VStack>
  );
}

useMessage

Send a message to a connection or a player.

import { useMessage } from 'react-node-insim';

function App() {
  const { sendMessageToConnection, sendMessageToPlayer } = useMessage();

  return (
    <>
      <Button
        top={5}
        left={10}
        width={15}
        height={5}
        onClick={(packet) => {
          sendMessageToConnection(
            packet.UCID,
            'Hello from React Node InSim',
            MessageSound.SND_SYSMESSAGE,
          );
        }}
      >
        Send message to a connection
      </Button>
      <Button
        top={10}
        left={10}
        width={15}
        height={5}
        onClick={(packet) => {
          sendMessageToPlayer(
            12, // PLID
            'Hello from React Node InSim',
            MessageSound.SND_SYSMESSAGE,
          );
        }}
      >
        Send message to a player
      </Button>
    </>
  );
}

useRaceControlMessage

Send a race control message (RCM) to a connection or a player.

import { useRaceControlMessage } from 'react-node-insim';

function App() {
  const { sendRaceControlMessageToConnection, sendRaceControlMessageToPlayer } =
    useRaceControlMessage();

  return (
    <>
      <Button
        top={5}
        left={10}
        width={15}
        height={5}
        onClick={(packet) => {
          sendRaceControlMessageToConnection(
            packet.UCID,
            'Hello from React Node InSim',
            2000,
          );
        }}
      >
        Send message to a connection
      </Button>
      <Button
        top={10}
        left={10}
        width={15}
        height={5}
        onClick={(packet) => {
          sendRaceControlMessageToPlayer(
            12, // PLID
            'Hello from React Node InSim',
            2000,
          );
        }}
      >
        Send message to a player
      </Button>
    </>
  );
}

useInSim

Access to Node InSim API of the current InSim client instance.

import { useInSim } from 'react-node-insim';

function App() {
  const inSim = useInSim();

  useEffect(() => {
    inSim.send(new IS_MST({ Msg: 'App mounted' }));
  }, []);

  return null;
}

Development

Requirements

Installation

yarn

Run example app

yarn start

Lint code

yarn lint

Format code

yarn format

React Node Insim - An open source project by Sim Broadcasts

FAQs

Package last updated on 26 Jun 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc