mirror of
https://github.com/Istador/smoo.it
synced 2025-10-05 23:42:42 +02:00
first commit
This commit is contained in:
3
.browserslistrc
Normal file
3
.browserslistrc
Normal file
@@ -0,0 +1,3 @@
|
||||
> 1%
|
||||
last 2 versions
|
||||
not dead
|
5
.editorconfig
Normal file
5
.editorconfig
Normal file
@@ -0,0 +1,5 @@
|
||||
[*.{js,jsx,ts,tsx,vue}]
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
26
.eslintrc.js
Normal file
26
.eslintrc.js
Normal file
@@ -0,0 +1,26 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: {
|
||||
node: true
|
||||
},
|
||||
extends: [
|
||||
'plugin:vue/essential',
|
||||
'@vue/standard',
|
||||
'@vue/typescript/recommended'
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: 2020
|
||||
},
|
||||
rules: {
|
||||
'indent' : [ 'error', 2 ],
|
||||
'linebreak-style' : [ 'error', 'unix' ],
|
||||
'quotes' : [ 'error', 'single' ],
|
||||
'semi' : [ 'error', 'never' ],
|
||||
'comma-dangle' : [ 'error', 'always-multiline' ],
|
||||
'no-var' : [ 'error' ],
|
||||
'no-multi-spaces' : [ 'error', { exceptions: { Property: true, TSPropertySignature: true } } ],
|
||||
'key-spacing' : [ 'error', { align: { beforeColon: true, afterColon: true, mode: 'minimum', on: 'colon' } } ],
|
||||
'no-console' : process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||
'no-debugger' : process.env.NODE_ENV === 'production' ? 'warn' : 'off'
|
||||
}
|
||||
}
|
67
.github/workflows/gh-pages.yaml
vendored
Normal file
67
.github/workflows/gh-pages.yaml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: gh-pages
|
||||
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ public ]
|
||||
pull_request:
|
||||
branches: [ public ]
|
||||
workflow_dispatch: # or manual
|
||||
|
||||
|
||||
permissions:
|
||||
contents : read
|
||||
pages : write
|
||||
id-token : write
|
||||
|
||||
|
||||
concurrency:
|
||||
group : ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress : true
|
||||
|
||||
|
||||
jobs:
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
-
|
||||
name : Checkout
|
||||
uses : actions/checkout@v3
|
||||
-
|
||||
name : Install node 16
|
||||
uses : actions/setup-node@v3
|
||||
with :
|
||||
node-version : 16
|
||||
-
|
||||
name : Install node_modules
|
||||
run : npm ci --legacy-peer-deps
|
||||
-
|
||||
name : Build static files
|
||||
run : npm run build
|
||||
-
|
||||
name : Build artifacts
|
||||
run : |
|
||||
cd ./dist/
|
||||
tar -cvf ../artifact.tar ./
|
||||
-
|
||||
name : Upload artifacts
|
||||
uses : actions/upload-artifact@v3
|
||||
with :
|
||||
name : github-pages
|
||||
path : artifact.tar
|
||||
if-no-files-found : error
|
||||
|
||||
deploy:
|
||||
needs:
|
||||
- build
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event_name != 'pull_request' }}
|
||||
environment:
|
||||
name : github-pages
|
||||
url : ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
-
|
||||
name : Deploy artifacts to github pages
|
||||
uses : actions/deploy-pages@v1
|
||||
id : deployment
|
23
.gitignore
vendored
Normal file
23
.gitignore
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
365
LICENSE.md
Normal file
365
LICENSE.md
Normal file
@@ -0,0 +1,365 @@
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
1. Definitions
|
||||
--------------
|
||||
|
||||
1.1. "Contributor"
|
||||
means each individual or legal entity that creates, contributes to
|
||||
the creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
means the combination of the Contributions of others (if any) used
|
||||
by a Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
means Source Code Form to which the initial Contributor has attached
|
||||
the notice in Exhibit A, the Executable Form of such Source Code
|
||||
Form, and Modifications of such Source Code Form, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
(a) that the initial Contributor has attached the notice described
|
||||
in Exhibit B to the Covered Software; or
|
||||
|
||||
(b) that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the
|
||||
terms of a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
means a work that combines Covered Software with other material, in
|
||||
a separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
means having the right to grant, to the maximum extent possible,
|
||||
whether at the time of the initial grant or subsequently, any and
|
||||
all of the rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
means any of the following:
|
||||
|
||||
(a) any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered
|
||||
Software; or
|
||||
|
||||
(b) any new file in Source Code Form that contains any Covered
|
||||
Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the
|
||||
License, by the making, using, selling, offering for sale, having
|
||||
made, import, or transfer of either its Contributions or its
|
||||
Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
means either the GNU General Public License, Version 2.0, the GNU
|
||||
Lesser General Public License, Version 2.1, the GNU Affero General
|
||||
Public License, Version 3.0, or any later versions of those
|
||||
licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that
|
||||
controls, is controlled by, or is under common control with You. For
|
||||
purposes of this definition, "control" means (a) the power, direct
|
||||
or indirect, to cause the direction or management of such entity,
|
||||
whether by contract or otherwise, or (b) ownership of more than
|
||||
fifty percent (50%) of the outstanding shares or beneficial
|
||||
ownership of such entity.
|
||||
|
||||
2. License Grants and Conditions
|
||||
--------------------------------
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
(a) under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims of such Contributor to make, use, sell, offer
|
||||
for sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
(a) for any code that a Contributor has removed from Covered Software;
|
||||
or
|
||||
|
||||
(b) for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
(c) under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights
|
||||
to grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
|
||||
in Section 2.1.
|
||||
|
||||
3. Responsibilities
|
||||
-------------------
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
(a) such Covered Software must also be made available in Source Code
|
||||
Form, as described in Section 3.1, and You must inform recipients of
|
||||
the Executable Form how they can obtain a copy of such Source Code
|
||||
Form by reasonable means in a timely manner, at a charge no more
|
||||
than the cost of distribution to the recipient; and
|
||||
|
||||
(b) You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter
|
||||
the recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty,
|
||||
or limitations of liability) contained within the Source Code Form of
|
||||
the Covered Software, except that You may alter any license notices to
|
||||
the extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
---------------------------------------------------
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Software due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description must
|
||||
be placed in a text file included with all distributions of the Covered
|
||||
Software under this License. Except to the extent prohibited by statute
|
||||
or regulation, such description must be sufficiently detailed for a
|
||||
recipient of ordinary skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
--------------
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically
|
||||
if You fail to comply with any of its terms. However, if You become
|
||||
compliant, then the rights granted under this License from a particular
|
||||
Contributor are reinstated (a) provisionally, unless and until such
|
||||
Contributor explicitly and finally terminates Your grants, and (b) on an
|
||||
ongoing basis, if such Contributor fails to notify You of the
|
||||
non-compliance by some reasonable means prior to 60 days after You have
|
||||
come back into compliance. Moreover, Your grants from a particular
|
||||
Contributor are reinstated on an ongoing basis if such Contributor
|
||||
notifies You of the non-compliance by some reasonable means, this is the
|
||||
first time You have received notice of non-compliance with this License
|
||||
from such Contributor, and You become compliant prior to 30 days after
|
||||
Your receipt of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
|
||||
end user license agreements (excluding distributors and resellers) which
|
||||
have been validly granted by You or Your distributors under this License
|
||||
prior to termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
-------------------------
|
||||
|
||||
Covered Software is provided under this License on an "as is"
|
||||
basis, without warranty of any kind, either expressed, implied, or
|
||||
statutory, including, without limitation, warranties that the
|
||||
Covered Software is free of defects, merchantable, fit for a
|
||||
particular purpose or non-infringing. The entire risk as to the
|
||||
quality and performance of the Covered Software is with You.
|
||||
Should any Covered Software prove defective in any respect, You
|
||||
(not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an
|
||||
essential part of this License. No use of any Covered Software is
|
||||
authorized under this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
--------------------------
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort
|
||||
(including negligence), contract, or otherwise, shall any
|
||||
Contributor, or anyone who distributes Covered Software as
|
||||
permitted above, be liable to You for any direct, indirect,
|
||||
special, incidental, or consequential damages of any character
|
||||
including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any
|
||||
and all other commercial damages or losses, even if such party
|
||||
shall have been informed of the possibility of such damages. This
|
||||
limitation of liability shall not apply to liability for death or
|
||||
personal injury resulting from such party's negligence to the
|
||||
extent applicable law prohibits such limitation. Some
|
||||
jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and
|
||||
limitation may not apply to You.
|
||||
|
||||
8. Litigation
|
||||
-------------
|
||||
|
||||
Any litigation relating to this License may be brought only in the
|
||||
courts of a jurisdiction where the defendant maintains its principal
|
||||
place of business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions.
|
||||
Nothing in this Section shall prevent a party's ability to bring
|
||||
cross-claims or counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
----------------
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides
|
||||
that the language of a contract shall be construed against the drafter
|
||||
shall not be used to construe this License against a Contributor.
|
||||
|
||||
10. Versions of the License
|
||||
---------------------------
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses
|
||||
|
||||
If You choose to distribute Source Code Form that is Incompatible With
|
||||
Secondary Licenses under the terms of this version of the License, the
|
||||
notice described in Exhibit B of this License must be attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
-------------------------------------------
|
||||
|
||||
This Source Code Form is subject to the terms of the Mozilla Public
|
||||
License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular
|
||||
file, then You may include the notice in a location (such as a LICENSE
|
||||
file in a relevant directory) where a recipient would be likely to look
|
||||
for such a notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
---------------------------------------------------------
|
||||
|
||||
This Source Code Form is "Incompatible With Secondary Licenses", as
|
||||
defined by the Mozilla Public License, v. 2.0.
|
24
README.md
Normal file
24
README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# smoo.it
|
||||
|
||||
## Project setup
|
||||
```
|
||||
npm install
|
||||
```
|
||||
|
||||
### Compiles and hot-reloads for development
|
||||
```
|
||||
npm run serve
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
npm run build
|
||||
```
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
npm run lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
5
babel.config.js
Normal file
5
babel.config.js
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/cli-plugin-babel/preset'
|
||||
]
|
||||
}
|
22570
package-lock.json
generated
Normal file
22570
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
67
package.json
Normal file
67
package.json
Normal file
@@ -0,0 +1,67 @@
|
||||
{
|
||||
"name": "smoo.it",
|
||||
"version": "0.1.0",
|
||||
"main": "src/main.ts",
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Istador/smoo.it.git"
|
||||
},
|
||||
"keywords": [
|
||||
"html",
|
||||
"js",
|
||||
"css",
|
||||
"vuejs"
|
||||
],
|
||||
"author": "Robin C. Ladiges",
|
||||
"license": "MPL-2.0",
|
||||
"licenses": [
|
||||
{
|
||||
"type": "MPL-2.0",
|
||||
"url": "https://github.com/Istador/smoo.it/raw/public/LICENSE.md"
|
||||
}
|
||||
],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Istador/smoo.it/issues"
|
||||
},
|
||||
"homepage": "https://www.smoo.it/",
|
||||
"dependencies": {
|
||||
"@babel/polyfill": "^7.11.5",
|
||||
"bootstrap": "^4.5.2",
|
||||
"bootstrap-vue": "^2.22.0",
|
||||
"core-js": "^3.8.3",
|
||||
"mutationobserver-shim": "^0.3.7",
|
||||
"popper.js": "^1.16.1",
|
||||
"portal-vue": "^2.1.7",
|
||||
"vue": "^2.6.14",
|
||||
"vue-class-component": "^7.2.3",
|
||||
"vue-country-flag": "^2.3.2",
|
||||
"vue-property-decorator": "^9.1.2",
|
||||
"vue-router": "^3.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "^5.4.0",
|
||||
"@typescript-eslint/parser": "^5.4.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.0",
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-plugin-router": "~5.0.0",
|
||||
"@vue/cli-plugin-typescript": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"@vue/eslint-config-standard": "^6.1.0",
|
||||
"@vue/eslint-config-typescript": "^9.1.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-import": "^2.25.3",
|
||||
"eslint-plugin-node": "^11.1.0",
|
||||
"eslint-plugin-promise": "^5.1.0",
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"sass": "^1.32.7",
|
||||
"sass-loader": "^12.0.0",
|
||||
"typescript": "~4.5.5",
|
||||
"vue-cli-plugin-bootstrap-vue": "~0.8.2",
|
||||
"vue-template-compiler": "^2.6.14"
|
||||
}
|
||||
}
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.2 KiB |
17
public/index.html
Normal file
17
public/index.html
Normal file
@@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
9
src/App.scss
Normal file
9
src/App.scss
Normal file
@@ -0,0 +1,9 @@
|
||||
@import "@/style/main.scss";
|
||||
|
||||
.app {
|
||||
font-family: $smoo-default-font;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
text-align: center;
|
||||
padding: 20px;
|
||||
}
|
24
src/App.vue
Normal file
24
src/App.vue
Normal file
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div class="app">
|
||||
<smoo-header/>
|
||||
<router-view/>
|
||||
<smoo-footer/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" src="./App.scss" />
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator'
|
||||
import SmooHeader from './components/SmooHeader.vue'
|
||||
import SmooFooter from './components/SmooFooter.vue'
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
SmooHeader,
|
||||
SmooFooter,
|
||||
},
|
||||
})
|
||||
export default class State extends Vue {
|
||||
}
|
||||
</script>
|
BIN
src/assets/extern.png
Normal file
BIN
src/assets/extern.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 184 B |
BIN
src/assets/logo.png
Normal file
BIN
src/assets/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 74 KiB |
107
src/components/SmooBtn.vue
Normal file
107
src/components/SmooBtn.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<b class="smoo-btn" :title="title">
|
||||
<span v-if="custom" :class="{ [btn]: true }">{{ btn }}</span>
|
||||
<b-icon v-else :icon="icon" :title="title"/>
|
||||
</b>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component, Prop } from 'vue-property-decorator'
|
||||
|
||||
const customBtns = ['ZL', 'L', 'ZR', 'R', 'A', 'B']
|
||||
type TBtn = 'ZL' | 'L' | 'ZR' | 'R' | 'A' | 'B' | 'DUp' | 'DDown' | 'DLeft' | 'DRight'
|
||||
|
||||
@Component({})
|
||||
export default class Servers extends Vue {
|
||||
private get btn () : TBtn|null {
|
||||
if (this.ZL) { return 'ZL' }
|
||||
if (this.L) { return 'L' }
|
||||
if (this.ZR) { return 'ZR' }
|
||||
if (this.R) { return 'R' }
|
||||
if (this.A) { return 'A' }
|
||||
if (this.B) { return 'B' }
|
||||
if (this.DUp) { return 'DUp' }
|
||||
if (this.DDown) { return 'DDown' }
|
||||
if (this.DLeft) { return 'DLeft' }
|
||||
if (this.DRight) { return 'DRight' }
|
||||
return null
|
||||
}
|
||||
|
||||
private get custom () { return customBtns.includes(this.btn) }
|
||||
|
||||
private get icon () : string {
|
||||
if (this.DUp) { return 'arrow-up-circle' }
|
||||
if (this.DDown) { return 'arrow-down-circle' }
|
||||
if (this.DLeft) { return 'arrow-left-circle' }
|
||||
if (this.DRight) { return 'arrow-right-circle' }
|
||||
return ''
|
||||
}
|
||||
|
||||
private get title () : string {
|
||||
if (this.custom) { return this.btn }
|
||||
return 'D-Pad ' + this.icon.split(1)
|
||||
}
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private ZL! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private L! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private ZR! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private R! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private A! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private B! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private DUp! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private DDown! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private DLeft! : boolean
|
||||
|
||||
@Prop({ required: false, type: Boolean, default: false })
|
||||
private DRight! : boolean
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.smoo-btn {
|
||||
.ZL, .L, .ZR, .R, .A, .B {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
border: 1px solid black;
|
||||
border-radius: 0.25em;
|
||||
width: 2.5em;
|
||||
font-size: 0.65em;
|
||||
letter-spacing: 0.2em;
|
||||
line-hieght: 1em;
|
||||
vertical-align: middle;
|
||||
padding-top: 0.2em;
|
||||
padding-left: 0.2em;
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.ZL, .L { border-top-left-radius: 1.2em; }
|
||||
.ZR, .R { border-top-right-radius: 1.2em; }
|
||||
|
||||
.A, .B {
|
||||
border-radius:
|
||||
1em; width: 2em;
|
||||
}
|
||||
|
||||
svg {
|
||||
background-color: #eee;
|
||||
border-radius: 1em;
|
||||
}
|
||||
}
|
||||
</style>
|
19
src/components/SmooFooter.vue
Normal file
19
src/components/SmooFooter.vue
Normal file
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<footer>
|
||||
<nav>
|
||||
<a href="https://github.com/Istador/smoo.it" class="extern" target="_blank">GitHub</a> |
|
||||
<a href="https://discord.gg/jYCueK2BqD" class="extern" target="_blank">Discord</a> |
|
||||
<a href="https://rcl.blackpinguin.de/contact" class="extern" target="_blank">Contact</a>
|
||||
</nav>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
footer {
|
||||
opacity: 0.5;
|
||||
filter: saturate(0);
|
||||
nav {
|
||||
padding: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
26
src/components/SmooHeader.vue
Normal file
26
src/components/SmooHeader.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<header>
|
||||
<img
|
||||
alt="Super Mario Odyssey: Online Logo"
|
||||
title="Super Mario Odyssey: Online"
|
||||
src="@/assets/logo.png"
|
||||
width="144"
|
||||
height="128"
|
||||
>
|
||||
<nav>
|
||||
<router-link :to="{ name: 'home' }">Home</router-link> |
|
||||
<router-link :to="{ name: 'servers' }">Servers</router-link> |
|
||||
<router-link :to="{ name: 'play' }">Play</router-link> |
|
||||
<router-link :to="{ name: 'host' }">Host</router-link> |
|
||||
<router-link :to="{ name: 'faq' }">FAQ</router-link>
|
||||
</nav>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
header {
|
||||
nav {
|
||||
padding: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
53
src/components/SmooServerState.vue
Normal file
53
src/components/SmooServerState.vue
Normal file
@@ -0,0 +1,53 @@
|
||||
<template>
|
||||
<b-icon
|
||||
:icon="icon"
|
||||
:animation="animation"
|
||||
:class="{ 'state-component': true, [ state ]: true }"
|
||||
:title="state"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.state-component {
|
||||
&.loading { color: orange; }
|
||||
&.offline { color: red; }
|
||||
&.online { color: green; }
|
||||
&.unknown { color: black; }
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component, Prop } from 'vue-property-decorator'
|
||||
|
||||
import { TServer, TState } from '@/types'
|
||||
|
||||
@Component({})
|
||||
export default class SmooServerState extends Vue {
|
||||
private state : TState = 'loading'
|
||||
|
||||
@Prop({ required: 'true' })
|
||||
private server! : TServer
|
||||
|
||||
private get icon () : string {
|
||||
switch (this.state) {
|
||||
case 'loading': return 'arrow-clockwise'
|
||||
case 'unknown': return 'circle'
|
||||
default: return 'circle-fill'
|
||||
}
|
||||
}
|
||||
|
||||
private get animation () : string {
|
||||
return (this.state === 'loading' ? 'spin' : '')
|
||||
}
|
||||
|
||||
mounted () {
|
||||
this.state = 'unknown'
|
||||
|
||||
// TODO: check servers / get data from a backend
|
||||
// const states = ['unknown', 'online', 'offline']
|
||||
// window.setTimeout(function () {
|
||||
// this.state = states[Math.floor(Math.random() * states.length)]
|
||||
// }.bind(this), 1000 + Math.floor(Math.random() * 2000))
|
||||
}
|
||||
}
|
||||
</script>
|
16
src/main.ts
Normal file
16
src/main.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
import Vue from 'vue'
|
||||
import '@babel/polyfill'
|
||||
import 'mutationobserver-shim'
|
||||
import './plugins/bootstrap-vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import SmooBtn from '@/components/SmooBtn.vue'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
Vue.component('SmooBtn', SmooBtn)
|
||||
|
||||
new Vue({
|
||||
router,
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
6
src/plugins/bootstrap-vue.js
vendored
Normal file
6
src/plugins/bootstrap-vue.js
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
import { BootstrapVue, BootstrapVueIcons } from 'bootstrap-vue'
|
||||
|
||||
Vue.use(BootstrapVue)
|
||||
Vue.use(BootstrapVueIcons)
|
45
src/router/index.ts
Normal file
45
src/router/index.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import Vue from 'vue'
|
||||
import VueRouter, { RouteConfig } from 'vue-router'
|
||||
|
||||
import Home from '../views/Home.vue'
|
||||
import Play from '../views/Play.vue'
|
||||
import Host from '../views/Host.vue'
|
||||
import Servers from '../views/Servers.vue'
|
||||
import FAQ from '../views/FAQ.vue'
|
||||
|
||||
Vue.use(VueRouter)
|
||||
|
||||
const routes: Array<RouteConfig> = [
|
||||
{
|
||||
name : 'home',
|
||||
path : '/',
|
||||
component : Home,
|
||||
},
|
||||
{
|
||||
name : 'play',
|
||||
path : '/play',
|
||||
component : Play,
|
||||
},
|
||||
{
|
||||
name : 'host',
|
||||
path : '/host',
|
||||
component : Host,
|
||||
},
|
||||
{
|
||||
name : 'servers',
|
||||
path : '/servers',
|
||||
component : Servers,
|
||||
},
|
||||
{
|
||||
name : 'faq',
|
||||
path : '/faq',
|
||||
component : FAQ,
|
||||
},
|
||||
]
|
||||
|
||||
const router = new VueRouter({
|
||||
mode: 'history',
|
||||
routes,
|
||||
})
|
||||
|
||||
export default router
|
11
src/shims-tsx.d.ts
vendored
Normal file
11
src/shims-tsx.d.ts
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
import Vue, { VNode } from 'vue'
|
||||
|
||||
declare global {
|
||||
namespace JSX {
|
||||
interface Element extends VNode {}
|
||||
interface ElementClass extends Vue {}
|
||||
interface IntrinsicElements {
|
||||
[elem: string]: any
|
||||
}
|
||||
}
|
||||
}
|
4
src/shims-vue.d.ts
vendored
Normal file
4
src/shims-vue.d.ts
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
export default Vue
|
||||
}
|
1
src/style/globals.scss
Normal file
1
src/style/globals.scss
Normal file
@@ -0,0 +1 @@
|
||||
$smoo-default-font: Avenir, Helvetica, Arial, sans-serif;
|
68
src/style/main.scss
Normal file
68
src/style/main.scss
Normal file
@@ -0,0 +1,68 @@
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
@import "~bootstrap-vue/src/index";
|
||||
|
||||
.card-body {
|
||||
text-align: left;
|
||||
text-align: justify;
|
||||
|
||||
-webkit-hyphens: auto;
|
||||
-moz-hyphens: auto;
|
||||
-ms-hyphens: auto;
|
||||
hyphens: auto;
|
||||
|
||||
:last-child { margin-bottom: 0; }
|
||||
}
|
||||
|
||||
ul {
|
||||
padding-left: 1em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
code {
|
||||
color: #576afd;
|
||||
}
|
||||
|
||||
a {
|
||||
cursor: pointer;
|
||||
color: #007700;
|
||||
text-decoration: underline;
|
||||
|
||||
&:focus, &:hover, &:not([href]) {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&.extern[href]:not(.btn) {
|
||||
color: #cc20dd;
|
||||
padding-right: 1.1em;
|
||||
background-position: right center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1em 1em;
|
||||
background-image: url(@/assets/extern.png);
|
||||
}
|
||||
|
||||
&.extern[href].btn::after {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
margin-left: 0.1em;
|
||||
background-position: right center;
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1em 1em;
|
||||
background-image: url(@/assets/extern.png);
|
||||
filter: saturate(0);
|
||||
}
|
||||
|
||||
nav & {
|
||||
text-decoration: none;
|
||||
outline: unset;
|
||||
|
||||
&.router-link-exact-active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&:focus, &:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
19
src/types/index.ts
Normal file
19
src/types/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
|
||||
interface IHost {
|
||||
host : string
|
||||
}
|
||||
|
||||
interface IIP {
|
||||
ip : string
|
||||
}
|
||||
|
||||
export type TServer = (IHost | IIP | (IHost & IIP)) & { port? : number }
|
||||
|
||||
export interface IServer {
|
||||
name : string
|
||||
server : TServer
|
||||
version? : string
|
||||
location? : { flag?: string, name: string }
|
||||
}
|
||||
|
||||
export type TState = 'loading' | 'offline' | 'online' | 'unknown'
|
186
src/views/FAQ.vue
Normal file
186
src/views/FAQ.vue
Normal file
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<div class="faq-view accordion">
|
||||
<b-card v-for="(item, i) in questions" :key="item.question" no-body>
|
||||
<b-card-header header-tag="header" v-b-toggle="'accordion-' + i">
|
||||
{{ item.question }}
|
||||
</b-card-header>
|
||||
<b-collapse :id="'accordion-' + i" visible accordion="questions">
|
||||
<b-card-body><component :is="{ template: '<div>' + item.answer + '</div>' }"/></b-card-body>
|
||||
</b-collapse>
|
||||
</b-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.faq-view {
|
||||
text-align: left;
|
||||
.card-header {
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
right: 1.25rem;
|
||||
margin: auto 0;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%234f4f4f'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 01.708 0L8 10.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z'/%3E%3C/svg%3E");
|
||||
background-repeat: no-repeat;
|
||||
background-size: 1.25rem;
|
||||
transition: transform .2s ease-in-out;
|
||||
}
|
||||
&.collapsed::after {
|
||||
}
|
||||
&.not-collapsed::after {
|
||||
background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%231266f1'%3E%3Cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 01.708 0L8 10.293l5.646-5.647a.5.5 0 01.708.708l-6 6a.5.5 0 01-.708 0l-6-6a.5.5 0 010-.708z'/%3E%3C/svg%3E");
|
||||
transform: rotate(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator'
|
||||
|
||||
@Component({})
|
||||
export default class FAQ extends Vue {
|
||||
questions = [
|
||||
{
|
||||
question : 'How do I control the mod?',
|
||||
answer : `
|
||||
<p>
|
||||
Main menu:
|
||||
<ul>
|
||||
<li><smoo-btn ZL/> + <smoo-btn A/> - Mod configuration</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Pause menu:
|
||||
<ul>
|
||||
<li><smoo-btn ZL/> + <smoo-btn A/> or <smoo-btn ZL/> + <smoo-btn B/> - Mod configuration</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In-game:
|
||||
<ul>
|
||||
<li><smoo-btn ZL/> + <smoo-btn DLeft/> - Enable/disable Hide & Seek [H&S]</li>
|
||||
<li>[H&S] <smoo-btn DUp/> - Switch between hider and seeker</li>
|
||||
<li>[H&S] [Hider] <smoo-btn DLeft/> - Decrease hiding time</li>
|
||||
<li>[H&S] [Hider] <smoo-btn DRight/> - Increase hiding time</li>
|
||||
<li>[H&S] [Hider] <smoo-btn ZL/> + <smoo-btn DDown/> - Reset hiding time</li>
|
||||
<li style="margin-top: 0.75em;"><smoo-btn R/> + <smoo-btn DUp/> - Open/close [Debug] menu</li>
|
||||
<li>[Debug] <smoo-btn R/> + <smoo-btn DLeft/> - Previous page</li>
|
||||
<li>[Debug] <smoo-btn R/> + <smoo-btn DRight/> - Next page</li>
|
||||
<li>[Debug] <smoo-btn L/> + <smoo-btn DLeft/> - Previous player</li>
|
||||
<li>[Debug] <smoo-btn L/> + <smoo-btn DRight/> - Next player</li>
|
||||
</ul>
|
||||
</p>
|
||||
`,
|
||||
},
|
||||
{
|
||||
question : 'How do I change the server I\'m connected to?',
|
||||
answer : `
|
||||
By one of these methods:
|
||||
<ul>
|
||||
<li>In the main or pause menu hold <smoo-btn ZL/> and press <smoo-btn A/> to enter the hidden options menu where you can <code>Change Server IP</code>.</li>
|
||||
<li>Hold/press <smoo-btn ZL/> while starting the game, will prompt you for the IP.</li>
|
||||
<li>Delete the <code>common.bin</code> file in the save directory.</li>
|
||||
</ul>
|
||||
`,
|
||||
},
|
||||
{
|
||||
question : 'How do I hack my Switch?',
|
||||
answer : `
|
||||
<p>
|
||||
You need an <a href="https://ismyswitchpatched.com/" class="extern" target="_blank">unpatched</a> older revision of the Nintendo Switch,
|
||||
a microSDXC card, and a USB-C connection cable.
|
||||
To make the RCM exploit safer and easier, it's advised to use a RCM jig.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Follow this <a href="https://nh-server.github.io/switch-guide/" class="extern" target="_blank">guide</a>
|
||||
or alternatively <a href="https://switch.homebrew.guide/" class="extern" target="_blank">this one</a>.
|
||||
</p>
|
||||
`,
|
||||
},
|
||||
{
|
||||
question : 'How do I obtain a SMO ROM for emulators?',
|
||||
answer : 'The only <i>legal</i> way to obtain a ROM is by dumping it from your hacked Switch.',
|
||||
},
|
||||
{
|
||||
question : 'Am I on SMO version 1.0.0?',
|
||||
answer : 'If the game shows a <code>Play in VR</code> button, then you are still on version 1.3.',
|
||||
},
|
||||
{
|
||||
question : 'Will the mod be available for SMO version 1.3 in the future?',
|
||||
answer : 'No, it\'s too much effort to develop and support different versions of the mod.',
|
||||
},
|
||||
{
|
||||
question : 'What is a public/private IPv4 address?',
|
||||
answer : `
|
||||
<p>
|
||||
A public IPv4 address is the address under which a computer is accessible on the internet by other computers.
|
||||
Usually your router receives a public IPv4 address from your ISP.
|
||||
But be aware that there are internet subscriptions that don't give you a public IPv4 address but only a IPv6 address (e.g. LTE, DS Lite).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Private IPv4 addresses are usually only used inside your home network or for VPN networks and aren't publicly reachable from the internet.
|
||||
You can easily detect them by their leading numbers:
|
||||
<code>10.x.x.x</code>, <code>172.[16-31].x.x</code>, and <code>192.168.x.x</code> are all private addresses.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Additionally <code>127.x.x.x</code> is reserved for the local computer.
|
||||
You can input <code>127.0.0.1</code> as the server IP in the <router-link :to="{ name: 'play' }">mod</router-link>,
|
||||
if you're playing with an emulator on the same computer that runs the <router-link :to="{ name: 'host' }">server</router-link>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>0.0.0.0</code> usually stands for an invalid IPv4 address.
|
||||
It is only valid in context of hosting a <router-link :to="{ name: 'host' }">server</router-link>
|
||||
inside the <code>settings.json</code> file to denote listining to connections from all networks.
|
||||
(On some systems it's a workable alias for <code>127.0.0.1</code>, but you should avoid using it.)
|
||||
</p>
|
||||
`,
|
||||
},
|
||||
{
|
||||
question : 'Does this mod work with IPv6?',
|
||||
answer : `
|
||||
No.
|
||||
The Nintendo Switch doesn't support IPv6 natively.
|
||||
As long as Nintendo doesn't change this, or there's a homebrew network stack that support it, this'll likely never change.
|
||||
`,
|
||||
},
|
||||
{
|
||||
question : 'How do I port forward?',
|
||||
answer : `
|
||||
<p>This depends on your concrete router model.</p>
|
||||
|
||||
<p>
|
||||
Usually you open the web interface of your router, login there, and search for an option that let you configure port forwarding.
|
||||
Common router addresses are:
|
||||
<ul>
|
||||
<li><a href="http://192.168.0.1/" class="extern" target="_blank">192.168.0.1</a></li>
|
||||
<li><a href="http://192.168.1.1/" class="extern" target="_blank">192.168.1.1</a></li>
|
||||
</ul>
|
||||
If you can't figure it out, check the outside of your router (usually there's a sticker on it),
|
||||
consult its manual, or check the default gateway of your network adapter.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Once you found the settings, you want to configure:
|
||||
<ul>
|
||||
<li>Port: <code>1027</code> (internal & external)</li>
|
||||
<li>Protocol: <code>TCP</code></li>
|
||||
</ul>
|
||||
Additionally you also need to say to which computer inside your network the port shall be forwarded to.
|
||||
You want to forward the port to the computer that runs the <router-link :to="{ name: 'host' }">server</router-link>.
|
||||
Most routers will give you the option to select one of the currently connected devices,
|
||||
but sometimes you need to provide its private IP address.
|
||||
</p>
|
||||
`,
|
||||
},
|
||||
]
|
||||
}
|
||||
</script>
|
80
src/views/Home.vue
Normal file
80
src/views/Home.vue
Normal file
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<b-card-group columns class="home-view">
|
||||
<div style="">
|
||||
<div class="yt-embed">
|
||||
<iframe
|
||||
src="https://www.youtube.com/embed/nXxnhvP_LEI"
|
||||
title="SMOO Trailer"
|
||||
frameborder="0"
|
||||
allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
|
||||
allowfullscreen
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<b-card header="Super Mario Odyssey: Online">
|
||||
<p>SMOO is an inofficial multiplayer mod for Super Mario Odyssey on the Nintendo Switch.</p>
|
||||
|
||||
<p>
|
||||
Features:
|
||||
<br/>
|
||||
<ul>
|
||||
<li>Explore Kingdoms together with up to 10 People</li>
|
||||
<li>Almost every capture in the game is synced between players</li>
|
||||
<li>Full 2D and Costume models syncing</li>
|
||||
<li>Moon Collection is shared between all players</li>
|
||||
<li>Custom Configuration Menu</li>
|
||||
<li>Support for custom gamemodes (WIP)</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Available Gamemodes:
|
||||
<br/>
|
||||
<ul>
|
||||
<li>Hide and Seek</li>
|
||||
</ul>
|
||||
</p>
|
||||
</b-card>
|
||||
</b-card-group>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.home-view {
|
||||
-moz-column-count: 1 !important;
|
||||
column-count: 1 !important;
|
||||
-moz-row-gap: 1.25rem;
|
||||
row-gap: 1.25rem;
|
||||
@media (min-width: 800px) {
|
||||
-moz-column-count: 2 !important;
|
||||
column-count: 2 !important;
|
||||
}
|
||||
|
||||
.yt-embed {
|
||||
margin-bottom: 15px;
|
||||
iframe {
|
||||
width: 100%;
|
||||
aspect-ratio: 16 / 9;
|
||||
}
|
||||
@supports not (aspect-ratio: 1) {
|
||||
position: relative;
|
||||
padding-bottom: 56.25%;
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator'
|
||||
|
||||
@Component({})
|
||||
export default class Home extends Vue {}
|
||||
</script>
|
33
src/views/Host.vue
Normal file
33
src/views/Host.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<b-card-group columns deck class="host-view">
|
||||
|
||||
<b-card header="Requirements">
|
||||
<ul>
|
||||
<li>Public IPv4 address</li>
|
||||
<li>Open port</li>
|
||||
<li>Computer</li>
|
||||
</ul>
|
||||
</b-card>
|
||||
|
||||
<b-card header="Links">
|
||||
<b-btn-group
|
||||
vertical
|
||||
style="width: 100%;"
|
||||
>
|
||||
<b-btn
|
||||
class="extern"
|
||||
variant="outline-secondary"
|
||||
href="https://github.com/Sanae6/SmoOnlineServer"
|
||||
target="_blank"
|
||||
>GitHub repository</b-btn>
|
||||
</b-btn-group>
|
||||
</b-card>
|
||||
</b-card-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator'
|
||||
|
||||
@Component({})
|
||||
export default class Host extends Vue {}
|
||||
</script>
|
41
src/views/Play.vue
Normal file
41
src/views/Play.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<b-card-group columns deck class="play-view">
|
||||
|
||||
<b-card header="Requirements">
|
||||
<ul>
|
||||
<li>Hacked Nintendo Switch</li>
|
||||
<li>Super Mario Odyssey version 1.0.0</li>
|
||||
<li>Internet connection</li>
|
||||
</ul>
|
||||
</b-card>
|
||||
|
||||
<b-card header="Links">
|
||||
<b-btn-group
|
||||
vertical
|
||||
style="width: 100%;"
|
||||
>
|
||||
<b-btn
|
||||
class="extern"
|
||||
variant="outline-secondary"
|
||||
href="https://github.com/CraftyBoss/SuperMarioOdysseyOnline"
|
||||
target="_blank"
|
||||
>GitHub repository</b-btn>
|
||||
|
||||
<b-btn
|
||||
class="extern"
|
||||
variant="outline-secondary"
|
||||
href="https://gamebanana.com/mods/384214"
|
||||
target="_blank"
|
||||
>Gamebanana</b-btn>
|
||||
</b-btn-group>
|
||||
</b-card>
|
||||
|
||||
</b-card-group>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator'
|
||||
|
||||
@Component({})
|
||||
export default class Play extends Vue {}
|
||||
</script>
|
231
src/views/Servers.vue
Normal file
231
src/views/Servers.vue
Normal file
@@ -0,0 +1,231 @@
|
||||
<template>
|
||||
<div class="servers-view">
|
||||
<b-table
|
||||
:items="servers"
|
||||
:fields="fields"
|
||||
striped
|
||||
>
|
||||
|
||||
<template #cell(state)="{ item: { server } }">
|
||||
<smoo-server-state :server="server"/>
|
||||
</template>
|
||||
|
||||
<template #cell(server)="{ item: { server: { host, ip } } }">
|
||||
<span class="host" v-if="host">{{ host }}</span>
|
||||
<br v-if="host && ip"/>
|
||||
<span class="ip" v-if="ip">{{ ip }}</span>
|
||||
</template>
|
||||
|
||||
<template #cell(port)="{ item: { server: { port } } }">
|
||||
<span>{{ port || defaultPort }}</span>
|
||||
</template>
|
||||
|
||||
<template #cell(location)="{ item }">
|
||||
<div>
|
||||
<span class="flag-icon">
|
||||
<country-flag
|
||||
:title="item.location.name"
|
||||
:country="item.location.flag"
|
||||
size="normal"
|
||||
rounded
|
||||
/>
|
||||
</span>
|
||||
<span class="name"> {{ item.location.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template #cell(version)="{ item: { version } }">
|
||||
<span v-html="version"/>
|
||||
</template>
|
||||
|
||||
</b-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.servers-view {
|
||||
table {
|
||||
width: auto;
|
||||
display: inline-block;
|
||||
thead {
|
||||
th {
|
||||
position: sticky !important;
|
||||
top: 0;
|
||||
background-color: white;
|
||||
z-index: 999;
|
||||
}
|
||||
}
|
||||
tbody {
|
||||
td { vertical-align: middle; }
|
||||
|
||||
.td-server {
|
||||
.host, .ip { font-family: monospace; }
|
||||
@media (min-width: 800px) {
|
||||
.host::before { content: 'Host: '; font-family: $smoo-default-font; font-weight: bold; }
|
||||
.ip::before { content: 'IPv4: '; font-family: $smoo-default-font; font-weight: bold; }
|
||||
}
|
||||
.host + br + .ip { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.td-port {
|
||||
font-family: monospace;
|
||||
&.default { opacity: 0.5; }
|
||||
}
|
||||
|
||||
.td-location {
|
||||
> div {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
> .flag-icon { margin-right: 0.5em; margin-top: -0.2em; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 800px) {
|
||||
td.td-location span.name { display: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
th.th-name { display: none; }
|
||||
td.td-name { display: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 550px) {
|
||||
th.th-version { display: none; }
|
||||
td.td-version { display: none; }
|
||||
}
|
||||
|
||||
@media (max-width: 450px) {
|
||||
th.th-state { display: none; }
|
||||
td.td-state { display: none; }
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component } from 'vue-property-decorator'
|
||||
|
||||
import CountryFlag from 'vue-country-flag'
|
||||
|
||||
import { IServer } from '@/types'
|
||||
import SmooServerState from '@/components/SmooServerState.vue'
|
||||
|
||||
const linkTree = (branch, label) => '<a href="https://github.com/Sanae6/SmoOnlineServer/commits/' + branch + '" class="extern" target="_blank">' + (label || branch) + '</a>'
|
||||
const packetFixes = linkTree('packet-fixes')
|
||||
const latest = linkTree('master', 'latest')
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
CountryFlag,
|
||||
SmooServerState,
|
||||
},
|
||||
})
|
||||
export default class Servers extends Vue {
|
||||
private defaultPort = 1027
|
||||
|
||||
private fields = [
|
||||
{
|
||||
key : 'state',
|
||||
tdClass : 'td-state',
|
||||
thClass : 'th-state',
|
||||
},
|
||||
{
|
||||
key : 'name',
|
||||
tdClass : 'td-name',
|
||||
thClass : 'th-name',
|
||||
sortable : true,
|
||||
sortDirection : 'asc',
|
||||
},
|
||||
{
|
||||
key : 'server',
|
||||
tdClass : 'td-server',
|
||||
thClass : 'th-server',
|
||||
},
|
||||
{
|
||||
key : 'port',
|
||||
tdClass : (v, k, i) => 'td-port' + ((i.server.port || this.defaultPort) === this.defaultPort ? ' default' : ''),
|
||||
thClass : 'th-port',
|
||||
sortable : true,
|
||||
sortByFormatted : true,
|
||||
sortDirection : 'asc',
|
||||
formatter : (v, k, i) => i.server.port || this.defaultPort,
|
||||
},
|
||||
{
|
||||
key : 'location',
|
||||
tdClass : 'td-location',
|
||||
thClass : 'th-location',
|
||||
sortable : true,
|
||||
sortDirection : 'asc',
|
||||
},
|
||||
{
|
||||
key : 'version',
|
||||
tdClass : 'td-version',
|
||||
thClass : 'th-version',
|
||||
sortable : true,
|
||||
sortDirection : 'desc',
|
||||
},
|
||||
]
|
||||
|
||||
private servers : IServer[] = [
|
||||
{
|
||||
name : 'Piplup',
|
||||
server : { host: 'piplup.smoo.it', ip: '51.178.136.142' },
|
||||
location : { flag: 'fr', name: 'France' },
|
||||
state : 'loading',
|
||||
},
|
||||
{
|
||||
name : 'Piplup (Temp)',
|
||||
server : { host: 'piplup.smoo.it', ip: '51.178.136.142', port: 1806 },
|
||||
location : { flag: 'fr', name: 'France' },
|
||||
version : packetFixes,
|
||||
state : 'loading',
|
||||
},
|
||||
{
|
||||
name : 'Sanae',
|
||||
server : { host: 'sanae.smoo.it', ip: '64.201.219.20' },
|
||||
location : { flag: 'ca', name: 'Canada' },
|
||||
state : 'loading',
|
||||
},
|
||||
{
|
||||
name : 'Parknich',
|
||||
server : { host: 'parknich.smoo.it', ip: '51.81.86.202' },
|
||||
location : { flag: 'us', name: 'US-East' },
|
||||
state : 'offline',
|
||||
},
|
||||
{
|
||||
name : 'fruityloops',
|
||||
server : { host: 'fruityloops.smoo.it', ip: '62.226.142.89' },
|
||||
location : { flag: 'de', name: 'Germany' },
|
||||
state : 'loading',
|
||||
},
|
||||
{
|
||||
name : 'f0c0s',
|
||||
server : { host: 'f0c0s.smoo.it', ip: '94.130.25.137' },
|
||||
location : { flag: 'de', name: 'Germany' },
|
||||
state : 'loading',
|
||||
},
|
||||
{
|
||||
name : 'beni',
|
||||
server : { host: 'beni.smoo.it', ip: '51.68.173.172' },
|
||||
location : { flag: 'de', name: 'Germany' },
|
||||
state : 'unknown',
|
||||
},
|
||||
{
|
||||
name : 'RCL',
|
||||
server : { host: 'rcl.smoo.it' },
|
||||
location : { flag: 'de', name: 'Germany' },
|
||||
version : latest,
|
||||
state : 'online',
|
||||
},
|
||||
{
|
||||
name : 'RCL',
|
||||
server : { host: 'rcl.smoo.it', port: 1028 },
|
||||
location : { flag: 'de', name: 'Germany' },
|
||||
version : packetFixes,
|
||||
state : 'online',
|
||||
},
|
||||
]
|
||||
}
|
||||
</script>
|
41
tsconfig.json
Normal file
41
tsconfig.json
Normal file
@@ -0,0 +1,41 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "esnext",
|
||||
"module": "esnext",
|
||||
"strict": true,
|
||||
"jsx": "preserve",
|
||||
"moduleResolution": "node",
|
||||
"experimentalDecorators": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"useDefineForClassFields": true,
|
||||
"sourceMap": true,
|
||||
"baseUrl": ".",
|
||||
"types": [
|
||||
"webpack-env"
|
||||
],
|
||||
"paths": {
|
||||
"@/*": [
|
||||
"src/*"
|
||||
]
|
||||
},
|
||||
"lib": [
|
||||
"esnext",
|
||||
"dom",
|
||||
"dom.iterable",
|
||||
"scripthost"
|
||||
]
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts",
|
||||
"src/**/*.tsx",
|
||||
"src/**/*.vue",
|
||||
"tests/**/*.ts",
|
||||
"tests/**/*.tsx"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules"
|
||||
]
|
||||
}
|
19
vue.config.js
Normal file
19
vue.config.js
Normal file
@@ -0,0 +1,19 @@
|
||||
const { defineConfig } = require('@vue/cli-service')
|
||||
|
||||
module.exports = defineConfig({
|
||||
transpileDependencies: true,
|
||||
runtimeCompiler: true,
|
||||
pages: {
|
||||
index: {
|
||||
entry : 'src/main.ts',
|
||||
title : 'Super Mario Odyssey: Online',
|
||||
},
|
||||
},
|
||||
css: {
|
||||
loaderOptions: {
|
||||
sass: {
|
||||
additionalData: '@import "@/style/globals.scss";',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
Reference in New Issue
Block a user