1.0.109 • Published 2 years ago

socket.io-games v1.0.109

Weekly downloads
-
License
ISC
Repository
github
Last release
2 years ago

Game Package

A package you can use to create your own game platform with an implemented match- and user-system with default games like TicTacToe using socket.io

Documentation

Typical Configuration

const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const socketGames = require('socket.io-games');

socketGames.config.config(app, {
  file: "./db.json",
  usernameCharacterLength: {
    minimum: 2, // default => 0 (no minimum)
    maximum: 15 // default => 0 (no maximum)
  }, // optional
  pluginURL: "https://myPluginURL.com" // default => official plugin site
}).then(() => {
  socketGames.config.clearDatabaseSync();
});
app.use(express.static("pages"));
app.use(express.static("public"));

io.on('connection', (socket, name) => {});

app.all('/', (req, res) => {
  res.sendFile("pages/home/index.html");
});

http.listen(3000, () => {
  console.log("Server is ready");
});

Configuration

Setup

socketGames.config.config(app, {
  file: "./db.json" // database
});

Read Database

socketGames.config.readDatabase().then((result) => {
  console.log(result.data);
});

Clear Database

socketGames.config.clearDatabase().then((result) => {
  console.log("Cleared the database");
});

Matches

Create Match

socket.on("createMatch", (options) => {
  socketGames.matches.createMatch(socket.id, options).then((result) => {
    if (!result.err) {
      io.of("/").sockets.get(result.playerId).emit("newMatch", result);
    }
  });
});

Accept Match

socket.on("acceptMatch", (options) => {
  socketGames.matches.acceptMatch(socket.id, options).then((result) => {
    if (!result.err) {
      socket.emit("acceptMatch", result);
    }
  });
});

Reject Match

socket.on("rejectMatch", (options) => {
  if (socketGames.config.readDatabaseSync().data.matches[options.matchId]?.status === "pending") {
    socketGames.matches.rejectMatch(socket.id, options).then((result) => {
      if (!result.err) {
        socket.emit("rejectMatch", result);
      }
    });
  }
});

Open Match

socket.on("openMatch", (options) => {
  try {
    socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.players.forEach((player) => {
      io.of("/").sockets.get(player).emit("openMatch", {
        matchId: options.matchId,
        turn: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data.turn,
        players: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data?.players,
        users: socketGames.users.allUsersSync().users
      });
    });
  } catch (err) {}
});

Users

Create User

socket.on("createUser", (options) => {
  socketGames.users.createUser(socket.id, options).then(() => {
    socketGames.users.allUsers().then(({ users }) => {
      io.emit("userUpdate", { users });
    });
  });
});

Edit User

socket.on("editUser", (options) => {
  socketGames.users.editUser(socket.id, options).then(() => {
    socketGames.users.allUsers().then(({ users }) => {
      io.emit("userUpdate", { users });
    })
  });
})

Delete User

socket.on("disconnect", () => {
  socketGames.users.deleteUser(socket.id, io).then((deletedUser) => {
    if (!deletedUser.err) {
      socketGames.users.allUsers().then(({ users }) => {
        io.emit("userUpdate", { users });
        deletedUser.matches.forEach((match) => {
          match[1].players.filter((player) => player !== socket.id).forEach((player) => {
            io.of("/").sockets.get(player).emit("roomLeave", {
              username: result.users[player].username
            });
          });
        });
      });
    }
  });
});

Games

Create Match of TicTacToe

socket.on("createMatch", (options) => {
  socketGames.games.tictactoe.createMatch(socket.id, options).then((result) => {
    if (!result.err) {
      io.of("/").sockets.get(result.playerId).emit("newMatch", result);
    }
  });
});

Create Match of Connect Four

socket.on("createMatch", (options) => {
  socketGames.games.connectfour.createMatch(socket.id, options).then((result) => {
    if (!result.err) {
      io.of("/").sockets.get(result.playerId).emit("newMatch", result);
    }
  });
});

Place Field of TicTacToe

socket.on("placeField", (options) => {
  try {
    socketGames.games.tictactoe.placeField(socket.id, options).then((result) => {
      if (!result.err) {
        Object.keys(result.players).forEach((player) => {
          io.of("/").sockets.get(player).emit("placeField", {
            ...result,
            ...{
              users: socketGames.users.allUsersSync().users
            }
          });
        });
      }
    });
  } catch (err) {}
});

Place Field of Connect Four

socket.on("placeField", (options) => {
  try {
    socketGames.games.connectfour.placeField(socket.id, options).then((result) => {
      if (!result.err) {
        Object.keys(result.players).forEach((player) => {
          io.of("/").sockets.get(player).emit("placeField", {
            ...result,
            ...{
              users: socketGames.users.allUsersSync().users
            }
          });
        });
      }
    });
  } catch (err) {}
});

Game Registry

Register File

socketGames.gameRegistry.registerGames({
  games: [
    {
      type: "file", // set type to file
      game: "./game.js" // path to your game
    }
  ]
});

Register URL

socketGames.gameRegistry.registerGames({
  games: [
    {
      type: "url", // set type to url
      game: "https://raw.githubusercontent.com/username/repository/root/file" // url to your game
    }
  ]
});

Register Plugin

socketGames.gameRegistry.registerGames({
  games: [
    {
      type: "plugin", // set type to plugin
      game: "My Plugin Id" // plugin id
    }
  ]
});

Unregister File

socketGames.gameRegistry.unregisterGames({
  games: [
    {
      type: "file", // set type to file
      game: "./game.js" // path to your game
    }
  ]
});

Unregister URL

socketGames.gameRegistry.unregisterGames({
  games: [
    {
      type: "url", // set type to url
      game: "https://raw.githubusercontent.com/username/repository/root/file" // url to your game
    }
  ]
});

Unregister Plugin

socketGames.gameRegistry.unregisterGames({
  games: [
    {
      type: "plugin", // set type to plugin
      game: "My Plugin Id" // plugin id
    }
  ]
});

Example

const express = require('express');
const app = express();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const socketGames = require('socket.io-games');

socketGames.config.config(app, {
  file: "./db.json"
}).then(() => {
  socketGames.config.clearDatabaseSync();
});
app.use(express.static("pages"));
app.use(express.static("public"));

io.on('connection', (socket, name) => {
  socket.on("createUser", (options) => {
    socketGames.users.createUser(socket.id, options).then(() => {
      socketGames.users.allUsers().then((result) => {
        io.emit("userUpdate", result.users);
      });
    });
  });
  socket.on("createMatch", (options) => {
    socketGames.games.tictactoe.createMatch(socket.id, options).then((result) => {
      if (!result.err) {
        io.of("/").sockets.get(result.playerId).emit("newMatch", result);
      }
    });
  });
  socket.on("acceptMatch", (options) => {
    socketGames.matches.acceptMatch(socket.id, options).then((result) => {
      if (!result.err) {
        socket.emit("acceptMatch", result);
      }
    });
  });
  socket.on("rejectMatch", (options) => {
    if (socketGames.config.readDatabaseSync().data.matches[options.matchId]?.status === "pending") {
      socketGames.matches.rejectMatch(socket.id, options).then((result) => {
        if (!result.err) {
          socket.emit("rejectMatch", result);
        }
      });
    }
  });
  socket.on("openMatch", (options) => {
    try {
      socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.players.forEach((player) => {
        io.of("/").sockets.get(player).emit("openMatch", {
          matchId: options.matchId,
          turn: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data.turn,
          players: socketGames.config.readDatabaseSync().data?.matches?.[options.matchId]?.data?.players,
          users: socketGames.users.allUsersSync().users
        });
      });
    } catch (err) {}
  });
  socket.on("placeField", (options) => {
    try {
      socketGames.games.tictactoe.placeField(socket.id, options).then((result) => {
        if (!result.err) {
          Object.keys(result.players).forEach((player) => {
            io.of("/").sockets.get(player).emit("placeField", {
              ...result,
              ...{
                users: socketGames.users.allUsersSync().users
              }
            });
          });
        }
      });
    } catch (err) {}
  });
  socket.on("disconnect", () => {
    socketGames.users.deleteUser(socket.id, io).then((deletedUser) => {
      if (!deletedUser.err) {
        socketGames.users.allUsers().then((result) => {
          io.emit("userUpdate", result.users);
          deletedUser.matches.forEach((match) => {
            match[1].players.filter((player) => player !== socket.id).forEach((player) => {
              io.of("/").sockets.get(player).emit("roomLeave", {
                username: result.users[player].username
              });
            });
          });
        });
      }
    });
  });
});

app.all('/', (req, res) => {
  res.sendFile("pages/home/index.html");
});

http.listen(3000, () => {
  console.log("Server is ready");
});

Client Side Documentation

Configuration

Setup

<script src="/socket.io/socket.io.js">
const socket = io();

Actions

Users

Create User
socket.emit("createUser", {
  username: "My Username"
});

Matches

Create Match
socket.emit("createMatch", {
  playerId: "player id"
});
Accept Match
socket.emit("acceptMatch", {
  matchId: "match id"
});
Reject Match
socket.emit("rejectMatch", {
  matchId: "match id"
});
Open Match
socket.emit("openMatch", {
  matchId: "match id"
});

Games

Place Field
socket.emit("placeField", {
  matchId: "match id",
  field: "1" // number from 1 to 9
})

Events

Users

User Update
socket.on("userUpdate", (options) => {
  console.log(options.users); // do some stuff with the users
});

Matches

New Match
socket.on("newMatch", (options) => {
  console.log(options.username, options.matchId); // do some stuff with the match request
});
Accept Match
socket.on("acceptMatch", (options) => {
  console.log(options.matchId); // do some stuff with the accepted match
  socket.emit("openMatch", { matchId: options.matchId }); // open the accepted match
});
Reject Match
socket.on("rejectMatch", (options) => {
  console.log(options.matchId); // do some stuff with the rejected match
});
Open Match
socket.on("openMatch", (options) => {
  console.log(options.users[socket.id], options.users[Object.entries(options.players).filter((item) => item[0] !== socket.id)[0][0]].username, options.turn); // do some stuff with the opened match
});

Games

Place Field
socket.on("placeField", (options) => {
  console.log(options.field); // do some stuff with the placed field
});

Rooms

Room Leave
socket.on("roomLeave", (options) => {
  console.log(options.username); // do some stuff with the user who left
});

Changelog

1.0.0 - Basic Version

Basic version of configuration, matches and users with TicTacToe and Connect Four as games

1.0.1 to 1.10 - Bug Fixes

Some bug fixes and updates for a better interface

1.11 to 1.20 - Game Updates

Updated games and security updates

1.21 - Templates (Client)

Templates (also called Client) added. Requires a http server or express app in config function

1.22 to 1.30 - Basic Updates

Some basic updates

1.31 - Leaderboard

Automatic leaderboard sorting for wins in all or specific games

1.32 - Game Engine (renamed to Game Registry)

Script to make adding custom games easy for beginners with file, urls and plugins (including plugin platform)

1.33 - Added data object to users and matches

Allow storing custom data in users and matches

1.34 to 1.42 - Bug fixes

Including fixing overwriting old fields

1.43 to 1.58 - Rock paper scissors

Added rock paper scissors as default game

1.59 - Added default options

Added default options which constains data about default changeable

1.60 to 1.72 - Bug fixes

Some bug fixes

1.73 to 1.80 - Memory

Added memory as default game

1.81 to 1.84 - Added shortcuts

Added shourtcuts with basically the same function as the game registry

1.85 - Added util functions

Added some util function

1.86 to 1.88 - Bug fixes

Some bug fixes

1.89 - Added random number generator

Added new util function called random number generator

1.90 to 1.94 - Bug fixes

Some bug fixes

1.95 to 1.96 - Added get quantity of each item

Added new util function called get quantity of each item

1.97 - Renamed read file

Renamed the read file function in config to read database

1.98 to 1.101 - Updated documentation

Updated the documentation in the readme file

1.102 to 1.104 - Added rounds

Added rounds to the default games

1.105 - Added changelog

Added changelog to the readme file

1.106 - Note and bugs

Added note and bugs to the readme file

1.107 to 1.109 - Bug fixes

Some bug fixes

Note

This package is based on promises, but every single function also contains a same synchronous function.

Bugs

Please report bugs in the following github repository: https://github.com/DinoscapeProgramming/Game-Package

Known issues

  • Fetch URL sync not working. Getting data from other web servers (also third party services) cannot be done synchronously. Use the asynchronous function instead.

Example Site

https://tictactoe.dinoscape.tk

1.0.107

2 years ago

1.0.106

2 years ago

1.0.109

2 years ago

1.0.108

2 years ago

1.0.105

2 years ago

1.0.104

2 years ago

1.0.102

2 years ago

1.0.101

2 years ago

1.0.100

2 years ago

1.0.99

2 years ago

1.0.98

2 years ago

1.0.97

2 years ago

1.0.96

2 years ago

1.0.95

2 years ago

1.0.94

2 years ago

1.0.93

2 years ago

1.0.92

2 years ago

1.0.91

2 years ago

1.0.90

2 years ago

1.0.89

2 years ago

1.0.88

2 years ago

1.0.87

2 years ago

1.0.86

2 years ago

1.0.85

2 years ago

1.0.84

2 years ago

1.0.83

2 years ago

1.0.82

2 years ago

1.0.81

2 years ago

1.0.80

2 years ago

1.0.79

2 years ago

1.0.78

2 years ago

1.0.77

2 years ago

1.0.76

2 years ago

1.0.75

2 years ago

1.0.74

2 years ago

1.0.73

2 years ago

1.0.72

2 years ago

1.0.71

2 years ago

1.0.70

2 years ago

1.0.69

2 years ago

1.0.68

2 years ago

1.0.67

2 years ago

1.0.66

2 years ago

1.0.65

2 years ago

1.0.64

2 years ago

1.0.63

2 years ago

1.0.62

2 years ago

1.0.61

2 years ago

1.0.60

2 years ago

1.0.59

2 years ago

1.0.58

2 years ago

1.0.57

2 years ago

1.0.56

2 years ago

1.0.55

2 years ago

1.0.54

2 years ago

1.0.53

2 years ago

1.0.52

2 years ago

1.0.51

2 years ago

1.0.50

2 years ago

1.0.49

2 years ago

1.0.48

2 years ago

1.0.47

2 years ago

1.0.46

2 years ago

1.0.45

2 years ago

1.0.44

2 years ago

1.0.43

2 years ago

1.0.42

2 years ago

1.0.41

2 years ago

1.0.40

2 years ago

1.0.39

2 years ago

1.0.38

2 years ago

1.0.37

2 years ago

1.0.36

2 years ago

1.0.35

2 years ago

1.0.34

2 years ago

1.0.33

2 years ago

1.0.32

2 years ago

1.0.31

2 years ago

1.0.30

2 years ago

1.0.29

2 years ago

1.0.28

2 years ago

1.0.27

2 years ago

1.0.26

2 years ago

1.0.25

2 years ago

1.0.24

2 years ago

1.0.23

2 years ago

1.0.22

2 years ago

1.0.21

2 years ago

1.0.20

2 years ago

1.0.19

2 years ago

1.0.18

2 years ago

1.0.17

2 years ago

1.0.16

2 years ago

1.0.15

2 years ago

1.0.14

2 years ago

1.0.13

2 years ago

1.0.12

2 years ago

1.0.11

2 years ago

1.0.10

2 years ago

1.0.9

2 years ago

1.0.8

2 years ago

1.0.7

2 years ago

1.0.6

2 years ago

1.0.5

2 years ago

1.0.4

2 years ago

1.0.3

2 years ago

1.0.2

2 years ago

1.0.1

2 years ago

1.0.0

2 years ago