58 Commits

Author SHA1 Message Date
d2d1b5bc9f fixed untracked files 2023-02-14 19:44:24 +00:00
888ad8acb7 fixed untracked files 2023-02-14 19:40:53 +00:00
e5d4381fd9 fixed untracked files 2023-02-14 19:35:57 +00:00
c7be50d3b7 fixed untracked files 2023-02-14 19:34:30 +00:00
1c06d5b882 changed module name 2023-02-14 19:33:22 +00:00
e1debe8f53 added more artwork 2023-02-14 09:45:39 +00:00
ba0e562fd7 removed path pointing to ansible file 2023-02-10 17:24:39 +00:00
afe4105e3a fixed plugin bug for spawning nodes in a TURN based environment 2023-02-10 17:19:28 +00:00
Akilan Selvacoumar
c42bf002de Merge pull request #88 from Akilan1999/NAT-traversal
Added mutex to avoid race condition when writing to iptable file
2023-01-26 08:00:32 +00:00
256998d964 added mutex to avoid race condition when writing to iptable file 2023-01-25 20:46:58 +00:00
f82f5f9ec8 fix learning nodes 2023-01-25 08:25:10 +00:00
Akilan Selvacoumar
1bc62cc2d1 Merge pull request #87 from Akilan1999/NAT-traversal
NAT Traversal with FRP and IPTables resolved
2023-01-25 01:18:43 +00:00
8f12781928 fixed changes to spwan docker container 2023-01-25 01:12:36 +00:00
280091f7b1 improved version of IPTable 2023-01-24 22:27:18 +00:00
8106277956 changed
duplication detection logic and added better ouput for nodes in the IPTable
2023-01-24 22:06:21 +00:00
f6c7a21601 changed the sceheduler 2023-01-24 13:22:42 +00:00
f7a3b72287 changed way network learns about nodes 2023-01-21 21:13:50 +00:00
160f544b8b indentation 2023-01-21 21:00:00 +00:00
52d9dd1b16 added possiblity to spwan docker container 2023-01-21 11:34:47 +00:00
15df4f45d5 testing docker again for lol 2023-01-21 03:59:23 +00:00
6f4fdf1a8e testing docker again for lol 2023-01-21 03:55:59 +00:00
b8820ff150 added back FRPDocker 2023-01-21 03:53:43 +00:00
67199a35ba commented FRP docker 2023-01-21 03:47:22 +00:00
dd2bf2e104 added docker port to be generated regular server 2023-01-18 22:28:31 +00:00
c5a7f85941 docker port map fix 2023-01-18 22:09:04 +00:00
1fb248d12d increased delay for starting FRP server 2023-01-17 18:50:39 +00:00
add0ae7fb6 fix https to http 2023-01-17 18:48:41 +00:00
c6ff05a9cb added FRPRandomPort 2023-01-17 18:40:43 +00:00
1cd4fa87d7 added route to auto create FRP port 2023-01-17 18:14:47 +00:00
120654a901 added hostname passthrough 2023-01-17 17:00:15 +00:00
f959b70ab9 fix: error response for docker 2022-12-29 14:58:31 +00:00
713500413c set print back to default 2022-12-29 03:46:21 +00:00
fb01428507 removed heavy test 50mb file 2022-12-29 03:44:14 +00:00
4deff38c07 added fix for reverse proxy 2022-12-29 03:40:36 +00:00
ede9674a08 base version working for reverse proxy 2022-12-29 03:17:42 +00:00
Akilan Selvacoumar
8a58aa6869 Update README.md 2022-12-02 02:13:23 +00:00
Akilan Selvacoumar
9f5c75c4ef Update README.md 2022-12-02 02:12:44 +00:00
Akilan Selvacoumar
f6da22733a Merge pull request #85 from Gaurav-Gosain/master
Created a pure HTML implementation of the p2prc Logo (Squashed 'artwork/' content from commit 21e1ad5)
2022-12-01 21:41:15 +00:00
Gaurav Gosain
a9f0488c4b testing git subtree 2022-12-01 13:06:00 +04:00
Gaurav Gosain
dec52e497c Merge commit '002235cf006da86b03655b57dd4bd4cf4c4924e6' as 'artwork' 2022-12-01 13:03:05 +04:00
Gaurav Gosain
002235cf00 Squashed 'artwork/' content from commit 21e1ad5
git-subtree-dir: artwork
git-subtree-split: 21e1ad52df667d8dfefd7840dcbe514fc955845b
2022-12-01 13:03:05 +04:00
2138ee2d5d added minor fixed to reverse proxy 2022-12-01 06:59:13 +00:00
4921a6345d added auto reverse proxy detection and applicable for docker container 2022-12-01 05:37:15 +00:00
7c0ddc79c9 added base NAT traveral using reverse proxy 2022-12-01 02:49:08 +00:00
fbfa0e47fa fixed mac darwin bug 2022-11-18 03:08:51 +00:00
Akilan Selvacoumar
80033e759a Merge pull request #83 from Gaurav-Gosain/master
Adds CI/CD workflow for website generation from the README Documentation
2022-09-18 23:39:00 +01:00
Gaurav Gosain
f1ed6c0e45 Update README.md 2022-09-18 22:48:50 +04:00
Gaurav Gosain
9e0b28bde5 Update README.md 2022-09-18 22:45:22 +04:00
Gaurav Gosain
f5c505160b Update pages.yml 2022-09-18 22:39:41 +04:00
Gaurav Gosain
0700f68543 Delete index.html 2022-09-18 22:38:39 +04:00
Gaurav Gosain
b5d77a1b72 Update README.md 2022-09-18 22:35:00 +04:00
Gaurav Gosain
536672a582 Create pages.yml 2022-09-18 22:33:18 +04:00
Gaurav Gosain
97292009dd Create _config.yml 2022-09-18 22:32:40 +04:00
Akilan Selvacoumar
4338adc9d5 Update README.md 2022-02-14 02:34:01 +04:00
Akilan Selvacoumar
a555c30db1 Merge pull request #80 from cr2007/master
P2PRC Website - Adds Dark Mode Support
2021-12-23 12:46:42 +04:00
CSK
9994847f90 Merge pull request #1 from cr2007/P2PRC-Website-DarkMode
P2PRC Website - Dark Mode
2021-12-22 13:18:50 +04:00
Chandrashekhar R
7531f678c6 Extra Commenting 2021-12-22 13:17:04 +04:00
Chandrashekhar R
6a25e540b2 Adds support for Dark Mode
Follows Material Design's Color standards for Dark Mode viewing and
appropriately applied it for the website
2021-12-22 13:15:12 +04:00
56 changed files with 1923 additions and 879 deletions

49
.github/workflows/pages.yml vendored Normal file
View File

@@ -0,0 +1,49 @@
name: Deploy Jekyll with GitHub Pages dependencies preinstalled
on:
# Runs on pushes targeting the default branch
push:
branches: ["main", "master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Build job
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v2
- name: Build with Jekyll
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
# Deployment job
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
needs: build
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

10
.gitignore vendored
View File

@@ -11,13 +11,23 @@ config.json
#ignore generated iptables #ignore generated iptables
p2p/iptable/ p2p/iptable/
!p2p/iptable/.gitkeep
#ignore plugins added #ignore plugins added
plugin/deploy/ plugin/deploy/
!plugin/deploy/.gitkeep
#ignore track container file #ignore track container file
client/trackcontainers/ client/trackcontainers/
!client/trackcontainers/.gitkeep
# Test generated files # Test generated files
generate/p2prctest generate/p2prctest
!generate/p2prctest/.gitkeep
generate/Test generate/Test
!generate/Test/.gitkeep
#ignore windows exe files #ignore windows exe files
*.exe *.exe
dist/ dist/
#MACOS .idea file
.DS_Store
.gitkeep

View File

@@ -1,3 +1,4 @@
<h1 align="center"> <h1 align="center">
<br> <br>
<a href=""><img src="https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/master/Docs/images/p2prclogo.png" alt="p2prc" width="400"></a> <a href=""><img src="https://raw.githubusercontent.com/Akilan1999/p2p-rendering-computation/master/Docs/images/p2prclogo.png" alt="p2prc" width="400"></a>
@@ -6,11 +7,12 @@
<!-- seperator --> <!-- seperator -->
<div style="display:flex;flex-wrap:wrap;">
[![GPLv2 license](https://img.shields.io/badge/License-GPLv2-blue.svg)](http://perso.crans.org/besson/LICENSE.html) <a href="http://perso.crans.org/besson/LICENSE.html"><img alt="GPLv2 license" src="https://img.shields.io/badge/License-GPLv2-blue.svg" style="padding:5px;margin:5px;" /></a>
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://GitHub.com/Akilan1999/p2p-rendering-computation/graphs/commit-activity) <a href="https://GitHub.com/Akilan1999/p2p-rendering-computation/graphs/commit-activity"><img alt="Maintenance" src="https://img.shields.io/badge/Maintained%3F-yes-green.svg" style="padding:5px;margin:5px;" /></a>
[![made-with-Go](https://img.shields.io/badge/Made%20with-Go-1f425f.svg)](http://golang.org) <a href="http://golang.org"><img alt="made-with-Go" src="https://img.shields.io/badge/Made%20with-Go-1f425f.svg" style="padding:5px;margin:5px;" /></a>
[![GoDoc reference example](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation) <a href="https://pkg.go.dev/git.sr.ht/~akilan1999/p2p-rendering-computation"><img alt="GoDoc reference example" src="https://img.shields.io/badge/godoc-reference-blue.svg" style="padding:5px;margin:5px;" /></a>
</div>
The main aim of this project was to create a custom peer to peer network. The user acting as the The main aim of this project was to create a custom peer to peer network. The user acting as the
client has total flexibility on how to batch the tasks and the user acting as the server has complete client has total flexibility on how to batch the tasks and the user acting as the server has complete
@@ -61,11 +63,11 @@ This project aims to create a peer to peer (p2p) network, where a user can use t
make install make install
``` ```
- If you look closely you will get outputs such as: - If you look closely you will get outputs such as:
```
// Add them to your .bashrc file // Add them to your .bashrc file
export P2PRC=/<path>/p2p-rendering-computation export P2PRC=/<path>/p2p-rendering-computation
export PATH=/<path>/p2p-rendering-computation:${PATH} export PATH=/<path>/p2p-rendering-computation:${PATH}
```
5. Test if it works 5. Test if it works
``` ```
@@ -98,4 +100,5 @@ As we are working on the open source project p2prc (i.e p2p network designed fo
or just providing feedback on new features to build or even just curious about new features added to the project. We have decided to create a discord group. or just providing feedback on new features to build or even just curious about new features added to the project. We have decided to create a discord group.
[![Support Server](https://discordapp.com/api/guilds/854397492795277322/widget.png?style=banner2)](https://discord.gg/b4nRGTjYqy) [![Support Server](https://discordapp.com/api/guilds/854397492795277322/widget.png?style=banner2)](https://discord.gg/b4nRGTjYqy)
[![Star History Chart](https://api.star-history.com/svg?repos=Akilan1999/p2p-rendering-computation&type=Date)](https://github.com/Gaurav-Gosain)

9
_config.yml Normal file
View File

@@ -0,0 +1,9 @@
remote_theme: abhinavs/moonwalk
favicon: "favicon-32x32.png" # relative path to site's favicon
theme_config:
appearance: "dark" # can be "light", "dark" or "auto"
appearance_toggle: true # if appearance can be switched by user
show_navbar: false
show_footer: false

16
artwork/README.md Normal file
View File

@@ -0,0 +1,16 @@
# p2prc_logo
## Pure HTML Version of the p2prc Logo :)
![p2prc Logo](https://user-images.githubusercontent.com/55647468/204634868-07e94b6d-65f5-4446-a11f-7a14f11edff9.png)
> Note: To change the size of the logo simply edit the CSS variable of `--size` under the `style` tag!
---
### Embedding the HTML as a `foreignObject` element inside an SVG directly
![](embed.svg)

46
artwork/embed.svg Normal file
View File

@@ -0,0 +1,46 @@
<svg width="800" height="800" xmlns="http://www.w3.org/2000/svg">
<foreignObject width="800" height="800">
<div xmlns="http://www.w3.org/1999/xhtml">
<style>
:root {
--size: 8;
}
.bg {
width: calc(var(--size)*100px);
height: calc(var(--size)*100px);
background: linear-gradient(90deg,
rgb(254, 188, 80) 30%,
rgb(235, 162, 118) 50%,
rgb(255, 97, 69) 70%);
-webkit-mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.p2prc {
position: fixed;
top: 63%;
font-size: calc((var(--size) * 100px)/8);
font-weight: 700;
font-family: sans-serif;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="logo">
<div class="bg"></div>
<div class="p2prc">p2prc</div>
</div>
</div>
</foreignObject>
</svg>

After

Width:  |  Height:  |  Size: 11 KiB

53
artwork/index.html Normal file
View File

@@ -0,0 +1,53 @@
<!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" />
<title>p2prc</title>
</head>
<body>
<style>
:root {
--size: 8;
}
.bg {
width: calc(var(--size)*100px);
height: calc(var(--size)*100px);
background: linear-gradient(
90deg,
rgb(254,188,80) 30%,
rgb(235,162,118) 50%,
rgb(255,97,69) 70%
);
-webkit-mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
-webkit-mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
mask-size: calc(var(--size)*100px) calc(var(--size)*100px);
mask-image: url("data:image/svg+xml;base64,PHN2ZyBpZD0iZTdReFVvNjhGTlMxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIg0KICAgIHZpZXdCb3g9IjAgMCA2MDAgNjAwIiBzaGFwZS1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiIgdGV4dC1yZW5kZXJpbmc9Imdlb21ldHJpY1ByZWNpc2lvbiI+DQogICAgPGc+DQogICAgICAgIDxsaW5lIHgxPSItMzIuNSIgeTE9Ii0xMy41IiB4Mj0iMzIuNSIgeTI9IjEzLjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDE5Mi41IDI1MS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTE3LjI1IiB5MT0iMjMuNzUiIHgyPSIxNy4yNSIgeTI9Ii0yMy43NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjA3Ljc1IDI4OC43NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iLTE3LjUiIHgyPSIyNC41IiB5Mj0iMTcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQ5LjUgMjgyLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjQuNSIgeTE9IjI1LjUiIHgyPSIyNC41IiB5Mj0iLTI1LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDI0OS41IDIzOS41KSIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjM2Y1Nzg3Ig0KICAgICAgICAgICAgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTMzLjI1IiB5MT0iLTE2LjI1IiB4Mj0iMzMuMjUiIHkyPSIxNi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjQwLjc1IDE5Ny4zMTAyNDkpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMTMiIHkxPSIyNyIgeDI9IjEzIiB5Mj0iLTI3IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyODYuMTIwNDk4IDE4NykiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzNmNTc4NyINCiAgICAgICAgICAgIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yMy43NSIgeTE9Ii0xOC44NzUiIHgyPSIyMy43NSIgeTI9IjE4Ljg3NSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzIyLjg3MDQ5OSAxNzguODc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTAuNSIgeTE9Ii00MC4zNzUiIHgyPSIwLjUiIHkyPSI0MC4zNzUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OCAyMzguMTI1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iMzcuMjUiIHkxPSIzMi4yNSIgeDI9Ii0zNy4yNSIgeTI9Ii0zMi4yNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzExLjI1IDI0Ni4yNSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9IjM2Ljc1IiB5MT0iLTExLjI1IiB4Mj0iLTM2Ljc1IiB5Mj0iMTEuMjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMxMC43NSAyODguNzUpIiBmaWxsPSJub25lIg0KICAgICAgICAgICAgc3Ryb2tlPSIjM2Y1Nzg3IiBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjEuMjUiIHkxPSItMTguMjUiIHgyPSIyMS4yNSIgeTI9IjE4LjI1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNjkuNzUgMjk1Ljc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgICAgICA8bGluZSB4MT0iLTIxLjUiIHkxPSItMTUuMTI1IiB4Mj0iMjEuNSIgeTI9IjE1LjEyNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMzY5LjUgMjEyLjg3NSkiIGZpbGw9Im5vbmUiDQogICAgICAgICAgICBzdHJva2U9IiMzZjU3ODciIHN0cm9rZS13aWR0aD0iOCIgLz4NCiAgICAgICAgPGxpbmUgeDE9Ii0yNC41IiB5MT0iMTYuNSIgeDI9IjI0LjUiIHkyPSItMTYuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoNDE1LjUgMjExLjUpIiBmaWxsPSJub25lIiBzdHJva2U9IiMzZjU3ODciDQogICAgICAgICAgICBzdHJva2Utd2lkdGg9IjgiIC8+DQogICAgICAgIDxsaW5lIHgxPSItMjMuMjUiIHkxPSItMjQuNzUiIHgyPSIyMy4yNSIgeTI9IjI0Ljc1IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MTQuMjUgMjUyLjc1KSIgZmlsbD0ibm9uZSINCiAgICAgICAgICAgIHN0cm9rZT0iIzNmNTc4NyIgc3Ryb2tlLXdpZHRoPSI4IiAvPg0KICAgIDwvZz4NCiAgICA8Zz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMDcuNSAxODEuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDMwMCAxNjApIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxMCIgcnk9IjEwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgxNjAgMjM4KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTQiIHJ5PSIxNCIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMjc0IDIxNCkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEyLjUiIHJ5PSIxMi41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgzNDcuNSAxOTcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjEwIiByeT0iMTAiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDQ0MCAxOTUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIyMCIgcnk9IjIwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyMjUgMjY1KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iMTguNSIgcnk9IjE4LjUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM0OC41IDI3OC41KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iNy41IiByeT0iNy41IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MzcuNSAyNzcuNSkiIGZpbGw9IiNkMmRiZWQiIHN0cm9rZS13aWR0aD0iMCIgLz4NCiAgICAgICAgPGVsbGlwc2Ugcng9IjcuNSIgcnk9IjcuNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTkwLjUgMzEyLjUpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgICAgIDxlbGxpcHNlIHJ4PSIxNCIgcnk9IjE0IiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyNzQgMjk5KSIgZmlsbD0iI2QyZGJlZCIgc3Ryb2tlLXdpZHRoPSIwIiAvPg0KICAgICAgICA8ZWxsaXBzZSByeD0iOSIgcnk9IjkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDM5MSAzMTQpIiBmaWxsPSIjZDJkYmVkIiBzdHJva2Utd2lkdGg9IjAiIC8+DQogICAgPC9nPg0KPC9zdmc+");
}
.logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border: 4px solid black;
border-radius: 2em;
}
.p2prc {
position: fixed;
top: 63%;
font-size: calc((var(--size) * 100px)/8);
font-weight: 700;
font-family: sans-serif;
left: 50%;
transform: translate(-50%, -50%);
}
</style>
<div class="logo">
<div class="bg"></div>
<div class="p2prc">p2prc</div>
</div>
</div>
</body>
</html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

View File

@@ -0,0 +1,11 @@
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_93)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="#3A3A3A"/>
<path d="M28.2947 139.433C26.2905 139.433 24.5369 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4969 134.083C18.6716 132.256 18.259 129.957 18.259 127.186C18.259 124.386 18.6569 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.9011 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5348 114.94 32.539 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.539 138.932 30.5348 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.1011 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.1011 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.1011 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3052 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8252 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6962 139.433C80.6919 139.433 78.9383 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8983 134.083C73.073 132.256 72.6604 129.957 72.6604 127.186C72.6604 124.386 73.0583 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6962 114.94C84.9362 114.94 86.9404 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9404 138.932 84.9362 139.433 82.6962 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2773 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2773ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#3A3A3A"/>
</g>
<defs>
<clipPath id="clip0_1_93">
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 433 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

View File

@@ -0,0 +1,15 @@
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_46)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="url(#paint0_linear_1_46)"/>
<path d="M28.2947 139.433C26.2905 139.433 24.5368 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4968 134.083C18.6716 132.256 18.2589 129.957 18.2589 127.186C18.2589 124.386 18.6568 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.9011 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5347 114.94 32.5389 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.5389 138.932 30.5347 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.1011 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.1011 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.1011 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3051 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8252 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6961 139.433C80.6919 139.433 78.9382 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8982 134.083C73.073 132.256 72.6603 129.957 72.6603 127.186C72.6603 124.386 73.0582 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6961 114.94C84.9361 114.94 86.9404 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9404 138.932 84.9361 139.433 82.6961 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2772 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2772ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#F5F5F5"/>
</g>
<defs>
<linearGradient id="paint0_linear_1_46" x1="145.974" y1="17.9477" x2="-4.68153e-06" y2="62.4661" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF593C"/>
<stop offset="1" stop-color="#FFBF57"/>
</linearGradient>
<clipPath id="clip0_1_46">
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

View File

@@ -0,0 +1,15 @@
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_41)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="url(#paint0_linear_1_41)"/>
<path d="M28.2947 139.433C26.2905 139.433 24.5368 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4968 134.083C18.6716 132.256 18.2589 129.957 18.2589 127.186C18.2589 124.386 18.6568 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.901 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5347 114.94 32.5389 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.5389 138.932 30.5347 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.101 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.101 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.101 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3051 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8251 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6961 139.433C80.6919 139.433 78.9382 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8982 134.083C73.073 132.256 72.6603 129.957 72.6603 127.186C72.6603 124.386 73.0582 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6961 114.94C84.9361 114.94 86.9403 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9403 138.932 84.9361 139.433 82.6961 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2772 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2772ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#3A3A3A"/>
</g>
<defs>
<linearGradient id="paint0_linear_1_41" x1="145.974" y1="17.9477" x2="-4.68153e-06" y2="62.4661" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF593C"/>
<stop offset="1" stop-color="#FFBF57"/>
</linearGradient>
<clipPath id="clip0_1_41">
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@@ -0,0 +1,19 @@
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_52)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="url(#paint0_linear_1_52)"/>
<path d="M28.2947 139.433C26.2905 139.433 24.5369 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4969 134.083C18.6716 132.256 18.259 129.957 18.259 127.186C18.259 124.386 18.6569 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.9011 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5348 114.94 32.539 115.456 34.3074 116.487C36.1053 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1432 124.711 40.1432 127.186C40.1432 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1053 136.927 34.3074 137.929C32.539 138.932 30.5348 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8232V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.1011 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0653 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0653 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.1011 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.1011 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4715 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4273 113.864 48.3073 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3052 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8252 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3473 109.487 61.6883 110.534 62.6315 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1894 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1073V139.079H41.7199ZM82.6962 139.433C80.6919 139.433 78.9383 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8983 134.083C73.073 132.256 72.6604 129.957 72.6604 127.186C72.6604 124.386 73.0583 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3025 116.266C78.8056 115.382 80.6035 114.94 82.6962 114.94C84.9362 114.94 86.9404 115.456 88.7088 116.487C90.5067 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5446 124.711 94.5446 127.186C94.5446 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5067 136.927 88.7088 137.929C86.9404 138.932 84.9362 139.433 82.6962 139.433ZM68.6372 147.656V115.294H75.2246V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5025 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4667 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4667 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5025 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5025 133.774ZM98.2773 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.903 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2773ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="url(#paint1_linear_1_52)"/>
</g>
<defs>
<linearGradient id="paint0_linear_1_52" x1="145.974" y1="17.9477" x2="-4.68153e-06" y2="62.4661" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF593C"/>
<stop offset="1" stop-color="#FFBF57"/>
</linearGradient>
<linearGradient id="paint1_linear_1_52" x1="135.617" y1="105.095" x2="21.0253" y2="154.798" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF593C"/>
<stop offset="1" stop-color="#FFBF57"/>
</linearGradient>
<clipPath id="clip0_1_52">
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -0,0 +1,11 @@
<svg width="151" height="150" viewBox="0 0 151 150" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_1_101)">
<path fill-rule="evenodd" clip-rule="evenodd" d="M76.6403 7.65789C76.6403 8.32645 76.5018 8.96264 76.252 9.53936L92.9656 22.3203C94.4069 20.7725 96.4626 19.8045 98.7444 19.8045C103.105 19.8045 106.639 23.3391 106.639 27.6992C106.639 28.8372 106.398 29.9189 105.965 30.8963L125.373 41.7419L140.792 28.173C140.62 27.6823 140.526 27.1547 140.526 26.6053C140.526 23.9892 142.647 21.8684 145.263 21.8684C147.879 21.8684 150 23.9892 150 26.6053C150 29.2213 147.879 31.3421 145.263 31.3421C144.06 31.3421 142.961 30.8934 142.126 30.1542L127.101 43.3758L143.687 67.2589C144.18 67.0849 144.71 66.9903 145.263 66.9903C147.879 66.9903 150 69.111 150 71.7271C150 74.3432 147.879 76.4639 145.263 76.4639C142.647 76.4639 140.526 74.3432 140.526 71.7271C140.526 70.5198 140.978 69.418 141.722 68.5815L124.71 44.0845L104.688 32.8957C103.39 34.3793 101.545 35.3725 99.4678 35.5612L98.1139 60.3828C101.679 61.7432 104.211 65.1943 104.211 69.2368C104.211 71.372 103.504 73.3422 102.312 74.9265L114.018 84.3809C114.807 83.7944 115.784 83.4474 116.842 83.4474C119.458 83.4474 121.579 85.5681 121.579 88.1842C121.579 90.8003 119.458 92.9211 116.842 92.9211C114.226 92.9211 112.105 90.8003 112.105 88.1842C112.105 87.4847 112.257 86.8205 112.529 86.2229L100.657 76.6336C99.035 77.9332 96.9767 78.7105 94.7368 78.7105C91.7849 78.7105 89.1482 77.3604 87.4108 75.2439L63.7377 81.6554C63.4383 84.2469 61.2365 86.2589 58.5648 86.2589C55.6887 86.2589 53.3572 83.9273 53.3572 81.0513C53.3572 80.5695 53.4226 80.103 53.5451 79.6601L39.0832 68.7042C37.3508 70.9489 34.6337 72.3947 31.5789 72.3947C30.1375 72.3947 28.7712 72.0728 27.5481 71.4969L18.8395 84.5598C19.871 85.4288 20.5263 86.7299 20.5263 88.1842C20.5263 90.8003 18.4056 92.9211 15.7895 92.9211C13.1734 92.9211 11.0526 90.8003 11.0526 88.1842C11.0526 85.5681 13.1734 83.4474 15.7895 83.4474C16.0935 83.4474 16.3909 83.476 16.6791 83.5308L25.548 70.2274C23.4453 68.4898 22.1053 65.8619 22.1053 62.9211C22.1053 61.6607 22.3514 60.4578 22.7982 59.3579L11.5333 54.5788C10.3959 56.2426 8.48337 57.3346 6.31579 57.3346C2.82767 57.3346 0 54.5069 0 51.0188C0 47.5307 2.82767 44.703 6.31579 44.703C9.80391 44.703 12.6316 47.5307 12.6316 51.0188C12.6316 51.4957 12.5787 51.9604 12.4785 52.4071L23.9665 57.2808C25.6928 54.9548 28.4598 53.4474 31.5789 53.4474C33.8143 53.4474 35.8689 54.2216 37.4891 55.5165L50.7399 42.6673C49.6198 41.3044 48.9474 39.5597 48.9474 37.6579C48.9474 36.3371 49.2717 35.092 49.8451 33.9981L30.7505 24.6728C29.3053 26.5154 27.0584 27.6992 24.5351 27.6992C20.1749 27.6992 16.6403 24.1646 16.6403 19.8045C16.6403 15.4443 20.1749 11.9097 24.5351 11.9097C28.8952 11.9097 32.4298 15.4443 32.4298 19.8045C32.4298 20.7915 32.2487 21.7362 31.9179 22.6071L51.2747 32.0605C52.7022 30.6406 54.6697 29.7632 56.8421 29.7632C57.9909 29.7632 59.0824 30.0085 60.067 30.4497L68.868 11.2945C67.8282 10.4256 67.1667 9.11898 67.1667 7.65789C67.1667 5.04181 69.2874 2.92105 71.9035 2.92105C74.5196 2.92105 76.6403 5.04181 76.6403 7.65789ZM63.4621 79.2763C62.7362 77.2741 60.8176 75.8437 58.5648 75.8437C57.0307 75.8437 55.6515 76.507 54.6984 77.5626L40.2913 66.6481C40.7813 65.5042 41.0526 64.2443 41.0526 62.9211C41.0526 60.7779 40.341 58.801 39.1411 57.2137L52.5045 44.2553C53.7493 45.0754 55.24 45.5526 56.8421 45.5526C59.3127 45.5526 61.5182 44.4178 62.9658 42.6409L86.6296 64.3327C85.7624 65.7633 85.2632 67.4418 85.2632 69.2368C85.2632 70.6299 85.5639 71.9528 86.1039 73.1441L63.4621 79.2763ZM71.9035 12.3947C71.5973 12.3947 71.2979 12.3657 71.0078 12.3102L62.0769 31.7481C63.7085 33.1944 64.7368 35.3061 64.7368 37.6579C64.7368 38.6789 64.543 39.6546 64.1902 40.5503L88.1046 62.4719C89.8135 60.7964 92.1545 59.7632 94.7368 59.7632C95.0869 59.7632 95.4325 59.7821 95.7727 59.8192L97.1034 35.4232C93.5308 34.6679 90.8497 31.4967 90.8497 27.6992C90.8497 26.4737 91.1289 25.3134 91.6272 24.2785L74.7972 11.4084C73.9968 12.0268 72.9931 12.3947 71.9035 12.3947Z" fill="#F5F5F5"/>
<path d="M28.2947 139.433C26.2905 139.433 24.5368 138.991 23.0337 138.106C21.5305 137.222 20.3516 135.881 19.4968 134.083C18.6716 132.256 18.2589 129.957 18.2589 127.186C18.2589 124.386 18.6568 122.087 19.4526 120.289C20.2484 118.492 21.3979 117.151 22.901 116.266C24.4042 115.382 26.2021 114.94 28.2947 114.94C30.5347 114.94 32.5389 115.456 34.3074 116.487C36.1052 117.489 37.52 118.904 38.5516 120.732C39.6126 122.559 40.1431 124.711 40.1431 127.186C40.1431 129.692 39.6126 131.858 38.5516 133.685C37.52 135.513 36.1052 136.927 34.3074 137.929C32.5389 138.932 30.5347 139.433 28.2947 139.433ZM14.2358 147.656V115.294H20.8231V120.157L20.6905 127.231L21.1326 134.26V147.656H14.2358ZM27.101 133.774C28.2505 133.774 29.2674 133.508 30.1516 132.978C31.0652 132.447 31.7874 131.696 32.3179 130.723C32.8779 129.721 33.1579 128.542 33.1579 127.186C33.1579 125.801 32.8779 124.622 32.3179 123.649C31.7874 122.677 31.0652 121.925 30.1516 121.395C29.2674 120.864 28.2505 120.599 27.101 120.599C25.9516 120.599 24.92 120.864 24.0063 121.395C23.0926 121.925 22.3705 122.677 21.84 123.649C21.3095 124.622 21.0442 125.801 21.0442 127.186C21.0442 128.542 21.3095 129.721 21.84 130.723C22.3705 131.696 23.0926 132.447 24.0063 132.978C24.92 133.508 25.9516 133.774 27.101 133.774ZM41.7199 139.079V134.437L53.6567 123.163C54.5999 122.308 55.2925 121.542 55.7346 120.864C56.1767 120.186 56.4714 119.567 56.6188 119.007C56.7957 118.447 56.8841 117.932 56.8841 117.46C56.8841 116.222 56.4567 115.279 55.602 114.631C54.7767 113.953 53.5536 113.614 51.9325 113.614C50.6357 113.614 49.4272 113.864 48.3072 114.365C47.2167 114.866 46.2883 115.647 45.522 116.708L40.3051 113.348C41.4841 111.58 43.1346 110.18 45.2567 109.148C47.3788 108.117 49.8251 107.601 52.5957 107.601C54.8946 107.601 56.8988 107.984 58.6083 108.751C60.3472 109.487 61.6883 110.534 62.6314 111.889C63.6041 113.245 64.0904 114.866 64.0904 116.753C64.0904 117.755 63.9578 118.757 63.6925 119.759C63.4567 120.732 62.9557 121.763 62.1893 122.854C61.4525 123.944 60.362 125.167 58.9178 126.523L49.0146 135.852L47.6441 133.243H65.1072V139.079H41.7199ZM82.6961 139.433C80.6919 139.433 78.9382 138.991 77.4351 138.106C75.9319 137.222 74.753 135.881 73.8982 134.083C73.073 132.256 72.6603 129.957 72.6603 127.186C72.6603 124.386 73.0582 122.087 73.854 120.289C74.6498 118.492 75.7993 117.151 77.3024 116.266C78.8056 115.382 80.6035 114.94 82.6961 114.94C84.9361 114.94 86.9403 115.456 88.7088 116.487C90.5066 117.489 91.9214 118.904 92.953 120.732C94.014 122.559 94.5445 124.711 94.5445 127.186C94.5445 129.692 94.014 131.858 92.953 133.685C91.9214 135.513 90.5066 136.927 88.7088 137.929C86.9403 138.932 84.9361 139.433 82.6961 139.433ZM68.6372 147.656V115.294H75.2245V120.157L75.0919 127.231L75.534 134.26V147.656H68.6372ZM81.5024 133.774C82.6519 133.774 83.6688 133.508 84.553 132.978C85.4666 132.447 86.1888 131.696 86.7193 130.723C87.2793 129.721 87.5593 128.542 87.5593 127.186C87.5593 125.801 87.2793 124.622 86.7193 123.649C86.1888 122.677 85.4666 121.925 84.553 121.395C83.6688 120.864 82.6519 120.599 81.5024 120.599C80.353 120.599 79.3214 120.864 78.4077 121.395C77.494 121.925 76.7719 122.677 76.2414 123.649C75.7109 124.622 75.4456 125.801 75.4456 127.186C75.4456 128.542 75.7109 129.721 76.2414 130.723C76.7719 131.696 77.494 132.447 78.4077 132.978C79.3214 133.508 80.353 133.774 81.5024 133.774ZM98.2772 139.079V115.294H104.865V122.014L103.936 120.068C104.644 118.388 105.778 117.121 107.34 116.266C108.902 115.382 110.804 114.94 113.044 114.94V121.306C112.749 121.277 112.484 121.262 112.248 121.262C112.012 121.233 111.761 121.218 111.496 121.218C109.61 121.218 108.077 121.763 106.898 122.854C105.749 123.915 105.174 125.58 105.174 127.849V139.079H98.2772ZM127.582 139.433C125.018 139.433 122.734 138.917 120.73 137.885C118.725 136.824 117.149 135.365 115.999 133.508C114.879 131.652 114.319 129.544 114.319 127.186C114.319 124.799 114.879 122.692 115.999 120.864C117.149 119.007 118.725 117.563 120.73 116.532C122.734 115.471 125.018 114.94 127.582 114.94C130.088 114.94 132.269 115.471 134.125 116.532C135.982 117.563 137.353 119.052 138.237 120.997L132.888 123.871C132.269 122.751 131.488 121.925 130.544 121.395C129.631 120.864 128.629 120.599 127.538 120.599C126.359 120.599 125.298 120.864 124.355 121.395C123.412 121.925 122.66 122.677 122.1 123.649C121.57 124.622 121.304 125.801 121.304 127.186C121.304 128.572 121.57 129.751 122.1 130.723C122.66 131.696 123.412 132.447 124.355 132.978C125.298 133.508 126.359 133.774 127.538 133.774C128.629 133.774 129.631 133.523 130.544 133.022C131.488 132.492 132.269 131.652 132.888 130.502L138.237 133.42C137.353 135.336 135.982 136.824 134.125 137.885C132.269 138.917 130.088 139.433 127.582 139.433Z" fill="#F5F5F5"/>
</g>
<defs>
<clipPath id="clip0_1_101">
<rect width="150" height="150" fill="white" transform="translate(0.5)"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 8.7 KiB

View File

@@ -3,7 +3,7 @@ package client
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/google/uuid" "github.com/google/uuid"
"io/ioutil" "io/ioutil"
"os" "os"
@@ -16,7 +16,7 @@ type Groups struct {
// Group Information about a single group // Group Information about a single group
type Group struct { type Group struct {
ID string `json:"ID"` ID string `json:"ID"`
TrackContainerList []*TrackContainer `json:"TrackContainer"` TrackContainerList []*TrackContainer `json:"TrackContainer"`
// Sneaky as required only when removing the element // Sneaky as required only when removing the element
// Set when GetGroup function is called // Set when GetGroup function is called
@@ -24,7 +24,7 @@ type Group struct {
} }
// CreateGroup Creates a new group to add a set of track containers // CreateGroup Creates a new group to add a set of track containers
func CreateGroup() (*Group, error){ func CreateGroup() (*Group, error) {
// Creating variable of type new group // Creating variable of type new group
var NewGroup Group var NewGroup Group
// Generate new UUID for group ID // Generate new UUID for group ID
@@ -40,7 +40,7 @@ func CreateGroup() (*Group, error){
return nil, err return nil, err
} }
return &NewGroup,nil return &NewGroup, nil
} }
// RemoveGroup Removes group based on the group ID provided // RemoveGroup Removes group based on the group ID provided
@@ -57,7 +57,7 @@ func RemoveGroup(GroupID string) error {
if err != nil { if err != nil {
return err return err
} }
// Remove Group struct from the groups variable // Remove Group struct from the groups variable
groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...) groups.GroupList = append(groups.GroupList[:group.index], groups.GroupList[group.index+1:]...)
// Write new groups to the grouptrackcontainer json file // Write new groups to the grouptrackcontainer json file
@@ -89,7 +89,7 @@ func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Updating specific element in the group list with the added container // Updating specific element in the group list with the added container
groups.GroupList[group.index] = group groups.GroupList[group.index] = group
// Write groups information on the grouptrackcontainer.json file // Write groups information on the grouptrackcontainer.json file
err = groups.WriteGroup() err = groups.WriteGroup()
@@ -101,21 +101,21 @@ func AddContainerToGroup(ContainerID string, GroupID string) (*Group, error) {
} }
// RemoveContainerGroup Remove Container from the group ID specified // RemoveContainerGroup Remove Container from the group ID specified
func RemoveContainerGroup(ContainerID string, GroupID string) (*Group,error) { func RemoveContainerGroup(ContainerID string, GroupID string) (*Group, error) {
// Get container information based on container ID provided // Get container information based on container ID provided
containerInfo, err := GetContainerInformation(ContainerID) containerInfo, err := GetContainerInformation(ContainerID)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Gets group information based on the group ID provided // Gets group information based on the group ID provided
group, err := GetGroup(GroupID) group, err := GetGroup(GroupID)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Remove container from the appropriate group // Remove container from the appropriate group
err = group.RemoveContainerGroup(containerInfo) err = group.RemoveContainerGroup(containerInfo)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Get Groups information from reading the grouptrackcontainer.json file // Get Groups information from reading the grouptrackcontainer.json file
groups, err := ReadGroup() groups, err := ReadGroup()
@@ -163,7 +163,7 @@ func RemoveContainerGroups(ContainerID string) error {
// GetGroup Gets group information based on // GetGroup Gets group information based on
// group id provided // group id provided
func GetGroup(GroupID string) (*Group,error) { func GetGroup(GroupID string) (*Group, error) {
// Read group information from the // Read group information from the
//grouptrackcontainer json file //grouptrackcontainer json file
groups, err := ReadGroup() groups, err := ReadGroup()
@@ -179,16 +179,16 @@ func GetGroup(GroupID string) (*Group,error) {
} }
} }
return nil,errors.New("Group not found. ") return nil, errors.New("Group not found. ")
} }
// AddGroupToFile Adds Group struct to the GroupTrackContainer File // AddGroupToFile Adds Group struct to the GroupTrackContainer File
func (grp *Group) AddGroupToFile() error { func (grp *Group) AddGroupToFile() error {
// Gets all group information from the // Gets all group information from the
// GroupTrackContainer JSON file // GroupTrackContainer JSON file
groups, err := ReadGroup() groups, err := ReadGroup()
if err != nil { if err != nil {
return err return err
} }
// Appending the newly created group // Appending the newly created group
groups.GroupList = append(groups.GroupList, grp) groups.GroupList = append(groups.GroupList, grp)
@@ -204,16 +204,16 @@ func (grp *Group) AddGroupToFile() error {
// ReadGroup Function reads grouptrackcontainers.json and converts // ReadGroup Function reads grouptrackcontainers.json and converts
// result to Groups // result to Groups
func ReadGroup() (*Groups,error) { func ReadGroup() (*Groups, error) {
// Get Path from config // Get Path from config
config, err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return nil,err return nil, err
} }
jsonFile, err := os.Open(config.GroupTrackContainersPath) jsonFile, err := os.Open(config.GroupTrackContainersPath)
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return nil,err return nil, err
} }
// defer the closing of our jsonFile so that we can parse it later on // defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close() defer jsonFile.Close()
@@ -227,9 +227,8 @@ func ReadGroup() (*Groups,error) {
return &groups, nil return &groups, nil
} }
// WriteGroup Function to write type Groups to the grouptrackcontainers.json file // WriteGroup Function to write type Groups to the grouptrackcontainers.json file
func (grp *Groups)WriteGroup() error { func (grp *Groups) WriteGroup() error {
file, err := json.MarshalIndent(grp, "", " ") file, err := json.MarshalIndent(grp, "", " ")
if err != nil { if err != nil {
return err return err
@@ -239,7 +238,7 @@ func (grp *Groups)WriteGroup() error {
if err != nil { if err != nil {
return err return err
} }
// Writes to the appropriate file // Writes to the appropriate file
err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644) err = ioutil.WriteFile(config.GroupTrackContainersPath, file, 0644)
if err != nil { if err != nil {
return err return err
@@ -248,13 +247,13 @@ func (grp *Groups)WriteGroup() error {
} }
// AddContainer Adds a container to the Tracked container list of the group // AddContainer Adds a container to the Tracked container list of the group
func (grp *Group)AddContainer(Container *TrackContainer) error { func (grp *Group) AddContainer(Container *TrackContainer) error {
grp.TrackContainerList = append(grp.TrackContainerList, Container) grp.TrackContainerList = append(grp.TrackContainerList, Container)
return nil return nil
} }
// RemoveContainerGroup Removes container information from the group // RemoveContainerGroup Removes container information from the group
func (grp *Group)RemoveContainerGroup(Container *TrackContainer) error { func (grp *Group) RemoveContainerGroup(Container *TrackContainer) error {
// Iterating through all container in the Group of Tracked Container // Iterating through all container in the Group of Tracked Container
for i, container := range grp.TrackContainerList { for i, container := range grp.TrackContainerList {
// If the container ID matches then remove the container from the group // If the container ID matches then remove the container from the group
@@ -266,9 +265,9 @@ func (grp *Group)RemoveContainerGroup(Container *TrackContainer) error {
} }
// RemoveContainerGroups removes container found in all groups // RemoveContainerGroups removes container found in all groups
func (grp *Groups)RemoveContainerGroups(Container *TrackContainer) error { func (grp *Groups) RemoveContainerGroups(Container *TrackContainer) error {
// Iterating through all groups // Iterating through all groups
for i,group := range grp.GroupList { for i, group := range grp.GroupList {
// Removes the container in the following group // Removes the container in the following group
// if it exists // if it exists
err := group.RemoveContainerGroup(Container) err := group.RemoveContainerGroup(Container)
@@ -283,7 +282,7 @@ func (grp *Groups)RemoveContainerGroups(Container *TrackContainer) error {
// ModifyContainerGroups Modifies container information is all groups // ModifyContainerGroups Modifies container information is all groups
// available // available
func (TC *TrackContainer)ModifyContainerGroups() error { func (TC *TrackContainer) ModifyContainerGroups() error {
group, err := ReadGroup() group, err := ReadGroup()
if err != nil { if err != nil {
return err return err
@@ -293,7 +292,7 @@ func (TC *TrackContainer)ModifyContainerGroups() error {
// ID matches // ID matches
for i, _ := range group.GroupList { for i, _ := range group.GroupList {
// Checking in each group if the modified container ID exists // Checking in each group if the modified container ID exists
for j, _:= range group.GroupList[i].TrackContainerList { for j, _ := range group.GroupList[i].TrackContainerList {
// If there is match then change them // If there is match then change them
if group.GroupList[i].TrackContainerList[j].Id == TC.Id { if group.GroupList[i].TrackContainerList[j].Id == TC.Id {
group.GroupList[i].TrackContainerList[j] = TC group.GroupList[i].TrackContainerList[j] = TC
@@ -308,4 +307,4 @@ func (TC *TrackContainer)ModifyContainerGroups() error {
} }
return nil return nil
} }

View File

@@ -2,7 +2,7 @@ package client
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"testing" "testing"
) )
@@ -46,14 +46,14 @@ func TestAddContainerToGroup(t *testing.T) {
// Creating and adding the container to the // Creating and adding the container to the
// tracked list // tracked list
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Testing the AddTrackContainer Function and adding the first container created // Testing the AddTrackContainer Function and adding the first container created
err = AddTrackContainer(container1,"0.0.0.0") err = AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
@@ -66,7 +66,7 @@ func TestAddContainerToGroup(t *testing.T) {
} }
// Adds container information to the group // Adds container information to the group
Group, err := AddContainerToGroup(container1.ID,group.ID) Group, err := AddContainerToGroup(container1.ID, group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -109,14 +109,14 @@ func TestGroup_RemoveContainerGroup(t *testing.T) {
// Creating and adding the container to the // Creating and adding the container to the
// tracked list // tracked list
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Testing the AddTrackContainer Function and adding the first container created // Testing the AddTrackContainer Function and adding the first container created
err = AddTrackContainer(container1,"0.0.0.0") err = AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
@@ -129,7 +129,7 @@ func TestGroup_RemoveContainerGroup(t *testing.T) {
} }
// Adds container information to the group // Adds container information to the group
Group, err := AddContainerToGroup(container1.ID,group.ID) Group, err := AddContainerToGroup(container1.ID, group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -138,7 +138,7 @@ func TestGroup_RemoveContainerGroup(t *testing.T) {
PrettyPrint(Group) PrettyPrint(Group)
// Removing docker container from the group // Removing docker container from the group
Group, err = RemoveContainerGroup(container1.ID,group.ID) Group, err = RemoveContainerGroup(container1.ID, group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -182,7 +182,7 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Created another group assigned to variable group 1 // Created another group assigned to variable group 1
group1, err := CreateGroup() group1, err := CreateGroup()
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@@ -191,14 +191,14 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
// Creating and adding the container to the // Creating and adding the container to the
// tracked list // tracked list
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Testing the AddTrackContainer Function and adding the first container created // Testing the AddTrackContainer Function and adding the first container created
err = AddTrackContainer(container1,"0.0.0.0") err = AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
@@ -211,7 +211,7 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
} }
// Adds container information to the group // Adds container information to the group
Group, err := AddContainerToGroup(container1.ID,group.ID) Group, err := AddContainerToGroup(container1.ID, group.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -220,7 +220,7 @@ func TestGroups_RemoveContainerGroups(t *testing.T) {
PrettyPrint(Group) PrettyPrint(Group)
// Adds container information to the group // Adds container information to the group
Group1, err := AddContainerToGroup(container1.ID,group1.ID) Group1, err := AddContainerToGroup(container1.ID, group1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()

View File

@@ -3,8 +3,7 @@ package client
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/server"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
) )
@@ -12,30 +11,30 @@ import (
// GetSpecs Gets Specs from the server such CPU, GPU usage // GetSpecs Gets Specs from the server such CPU, GPU usage
// and other basic information which helps set a // and other basic information which helps set a
// cluster of computer // cluster of computer
func GetSpecs(IP string)(*server.SysInfo,error) { func GetSpecs(IP string) (*server.SysInfo, error) {
var URL string var URL string
version := p2p.Ip4or6(IP) //version := p2p.Ip4or6(IP)
//Get port number of the server //Get port number of the server
serverPort, err := GetServerPort(IP) //serverPort, err := GetServerPort(IP)
if err != nil { //if err != nil {
return nil, err // return nil, err
} //}
if version == "version 6" { //if version == "version 6" {
URL = "http://[" + IP + "]:" + serverPort + "/server_info" URL = "http://" + IP + "/server_info"
} else { //} else {
URL = "http://" + IP + ":" + serverPort + "/server_info" // URL = "http://" + IP + ":" + serverPort + "/server_info"
} //}
resp, err := http.Get(URL) resp, err := http.Get(URL)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Convert response to byte value // Convert response to byte value
byteValue, err := ioutil.ReadAll(resp.Body) byteValue, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Create variable for result response type // Create variable for result response type
@@ -44,7 +43,7 @@ func GetSpecs(IP string)(*server.SysInfo,error) {
// Adds byte value to docker.DockerVM struct // Adds byte value to docker.DockerVM struct
json.Unmarshal(byteValue, &serverSpecsResult) json.Unmarshal(byteValue, &serverSpecsResult)
if err != nil { if err != nil {
return nil,err return nil, err
} }
return &serverSpecsResult, nil return &serverSpecsResult, nil
@@ -61,4 +60,4 @@ func PrettyPrint(data interface{}) {
return return
} }
fmt.Printf("%s \n", p) fmt.Printf("%s \n", p)
} }

View File

@@ -4,38 +4,38 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"io/ioutil" "io/ioutil"
"os" "os"
) )
// TrackContainers This struct stores arrays of current containers running // TrackContainers This struct stores arrays of current containers running
type TrackContainers struct { type TrackContainers struct {
TrackContainerList []TrackContainer `json:"TrackContainer"` TrackContainerList []TrackContainer `json:"TrackContainer"`
} }
// TrackContainer Stores information of current containers // TrackContainer Stores information of current containers
type TrackContainer struct { type TrackContainer struct {
Id string `json:"ID"` Id string `json:"ID"`
Container *docker.DockerVM `json:"Container"` Container *docker.DockerVM `json:"Container"`
IpAddress string `json:"IpAddress"` IpAddress string `json:"IpAddress"`
} }
// AddTrackContainer Adds new container which has been added to the track container // AddTrackContainer Adds new container which has been added to the track container
func AddTrackContainer(d *docker.DockerVM,ipAddress string) error { func AddTrackContainer(d *docker.DockerVM, ipAddress string) error {
// Checking if pointer d is null // Checking if pointer d is null
if d == nil { if d == nil {
return errors.New("d is nil") return errors.New("d is nil")
} }
//Get config information to derive paths for track containers json file //Get config information to derive paths for track containers json file
config,err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return err return err
} }
// Getting information about the file trackcontainers.json file // Getting information about the file trackcontainers.json file
stat, err := os.Stat(config.TrackContainersPath) stat, err := os.Stat(config.TrackContainersPath)
if err != nil { if err != nil {
return err return err
} }
@@ -66,11 +66,11 @@ func AddTrackContainer(d *docker.DockerVM,ipAddress string) error {
trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer) trackContainers.TrackContainerList = append(trackContainers.TrackContainerList, trackContainer)
// write modified information to the tracked json file // write modified information to the tracked json file
data,err := json.MarshalIndent(trackContainers, "", "\t") data, err := json.MarshalIndent(trackContainers, "", "\t")
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.TrackContainersPath,data,0777) err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
if err != nil { if err != nil {
return err return err
} }
@@ -81,7 +81,7 @@ func AddTrackContainer(d *docker.DockerVM,ipAddress string) error {
// RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file // RemoveTrackedContainer This function removos tracked container from the trackcontainer JSON file
func RemoveTrackedContainer(id string) error { func RemoveTrackedContainer(id string) error {
//Get config information to derive paths for track containers json file //Get config information to derive paths for track containers json file
config,err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return err return err
} }
@@ -104,11 +104,11 @@ func RemoveTrackedContainer(id string) error {
trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...) trackedContainers.TrackContainerList = append(trackedContainers.TrackContainerList[:removeElement], trackedContainers.TrackContainerList[removeElement+1:]...)
// write modified information to the tracked json file // write modified information to the tracked json file
data,err := json.MarshalIndent(trackedContainers, "", "\t") data, err := json.MarshalIndent(trackedContainers, "", "\t")
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.TrackContainersPath,data,0777) err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
if err != nil { if err != nil {
return err return err
} }
@@ -117,17 +117,17 @@ func RemoveTrackedContainer(id string) error {
} }
// ViewTrackedContainers View Containers currently tracked // ViewTrackedContainers View Containers currently tracked
func ViewTrackedContainers() (error,*TrackContainers) { func ViewTrackedContainers() (error, *TrackContainers) {
config,err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return err,nil return err, nil
} }
trackedContianers, err := ReadTrackContainers(config.TrackContainersPath) trackedContianers, err := ReadTrackContainers(config.TrackContainersPath)
if err != nil { if err != nil {
return err,nil return err, nil
} }
return nil,trackedContianers return nil, trackedContianers
} }
// ReadTrackContainers Reads containers which are currently tracked // ReadTrackContainers Reads containers which are currently tracked
@@ -167,7 +167,7 @@ func GetContainerInformation(ID string) (*TrackContainer, error) {
} }
// ModifyContainerInformation Modifies information inside the container // ModifyContainerInformation Modifies information inside the container
func (TC *TrackContainer)ModifyContainerInformation() error { func (TC *TrackContainer) ModifyContainerInformation() error {
// Gets all the information of tracker containers // Gets all the information of tracker containers
err, t := ViewTrackedContainers() err, t := ViewTrackedContainers()
if err != nil { if err != nil {
@@ -192,15 +192,15 @@ func (TC *TrackContainer)ModifyContainerInformation() error {
} }
// WriteContainers Write information back to the config file // WriteContainers Write information back to the config file
func (TC *TrackContainers)WriteContainers() error { func (TC *TrackContainers) WriteContainers() error {
// Initialize config file // Initialize config file
config,err := config.ConfigInit() config, err := config.ConfigInit()
// write modified information to the tracked json file // write modified information to the tracked json file
data,err := json.MarshalIndent(TC, "", "\t") data, err := json.MarshalIndent(TC, "", "\t")
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(config.TrackContainersPath,data,0777) err = ioutil.WriteFile(config.TrackContainersPath, data, 0777)
if err != nil { if err != nil {
return err return err
} }
@@ -209,12 +209,12 @@ func (TC *TrackContainers)WriteContainers() error {
} }
// CheckID Checks if the ID belongs to a group or a single container // CheckID Checks if the ID belongs to a group or a single container
func CheckID(ID string) (string,error) { func CheckID(ID string) (string, error) {
// For group checks if the 1st characters is "grp" // For group checks if the 1st characters is "grp"
if ID[0:3] == "grp" { if ID[0:3] == "grp" {
return "group", nil return "group", nil
} else { } else {
return "container", nil return "container", nil
} }
return "",nil return "", nil
} }

View File

@@ -2,20 +2,20 @@ package client
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"testing" "testing"
) )
// Tests a scenario where the container are getting tracked // Tests a scenario where the container are getting tracked
func TestAddTrackContainer(t *testing.T) { func TestAddTrackContainer(t *testing.T) {
// Create docker container and get SSH port // Create docker container and get SSH port
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Testing the AddTrackContainer Function // Testing the AddTrackContainer Function
err = AddTrackContainer(container1,"0.0.0.0") err = AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
@@ -26,7 +26,7 @@ func TestAddTrackContainer(t *testing.T) {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@@ -38,20 +38,20 @@ func TestAddTrackContainer(t *testing.T) {
// NOTE: This test can also be considered as a whole flow on the process of // NOTE: This test can also be considered as a whole flow on the process of
// tracked containers // tracked containers
func TestRemoveTrackedContainer(t *testing.T) { func TestRemoveTrackedContainer(t *testing.T) {
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
container2 ,err := docker.BuildRunContainer(0,"false","") container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Testing the AddTrackContainer Function and adding the first container created // Testing the AddTrackContainer Function and adding the first container created
err = AddTrackContainer(container1,"0.0.0.0") err = AddTrackContainer(container1, "0.0.0.0")
if err != nil { if err != nil {
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container1.ID) err = docker.StopAndRemoveContainer(container1.ID)
@@ -70,7 +70,7 @@ func TestRemoveTrackedContainer(t *testing.T) {
} }
// Testing the AddTrackContainer Function and the adding the second container created // Testing the AddTrackContainer Function and the adding the second container created
err = AddTrackContainer(container2,"0.0.0.0") err = AddTrackContainer(container2, "0.0.0.0")
if err != nil { if err != nil {
// Killing docker container created // Killing docker container created
err = docker.StopAndRemoveContainer(container2.ID) err = docker.StopAndRemoveContainer(container2.ID)
@@ -106,7 +106,7 @@ func TestRemoveTrackedContainer(t *testing.T) {
// Test function that checks if the ID belongs to // Test function that checks if the ID belongs to
// a group or container running // a group or container running
func TestCheckID(t *testing.T) { func TestCheckID(t *testing.T) {
id := "grp123" id := "grp123"
checkID, err := CheckID(id) checkID, err := CheckID(id)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)

View File

@@ -1,19 +1,22 @@
package client package clientIPTable
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"io" "io"
"io/ioutil" "io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
"os" "os"
"sync"
) )
var mu sync.Mutex
// UpdateIpTable Does the following to update it's IP table // UpdateIpTable Does the following to update it's IP table
func UpdateIpTable(IpAddress string, serverPort string) error { func UpdateIpTable(IpAddress string, serverPort string, wg *sync.WaitGroup) error {
config, err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
@@ -22,17 +25,16 @@ func UpdateIpTable(IpAddress string, serverPort string) error {
client := http.Client{} client := http.Client{}
var resp []byte var resp []byte
version := p2p.Ip4or6(IpAddress) version := p2p.Ip4or6(IpAddress)
if version == "version 6" { if version == "version 6" {
resp, err = UploadMultipartFile(client,"http://[" + IpAddress + "]:" + serverPort + "/IpTable","json",config.IPTable) resp, err = UploadMultipartFile(client, "http://["+IpAddress+"]:"+serverPort+"/IpTable", "json", config.IPTable)
if err != nil { if err != nil {
return err return err
} }
} else { } else {
resp, err = UploadMultipartFile(client,"http://" + IpAddress + ":" + serverPort + "/IpTable","json",config.IPTable) resp, err = UploadMultipartFile(client, "http://"+IpAddress+":"+serverPort+"/IpTable", "json", config.IPTable)
if err != nil { if err != nil {
return err return err
} }
@@ -62,16 +64,27 @@ func UpdateIpTable(IpAddress string, serverPort string) error {
} }
} }
err = ipStruct.WriteIpTable()
if err != nil {
return err
}
wg.Done()
return nil return nil
} }
// UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available // UpdateIpTableListClient updates IP tables (Default 3 hops) based on server information available
//on the ip tables // on the ip tables
func UpdateIpTableListClient() error { func UpdateIpTableListClient() error {
// Get config information
Config, err := config.ConfigInit()
if err != nil {
return err
}
// Ensure that the IP Table has Node pingable // Ensure that the IP Table has Node pingable
err := p2p.LocalSpeedTestIpTable() err = p2p.LocalSpeedTestIpTable()
if err != nil { if err != nil {
return err return err
} }
@@ -80,52 +93,57 @@ func UpdateIpTableListClient() error {
// duplication // duplication
Addresses, err := p2p.ReadIpTable() Addresses, err := p2p.ReadIpTable()
//var DoNotRead p2p.IpAddresses var DoNotRead p2p.IpAddresses
// Run loop 3 times currentIPV4, err := p2p.CurrentPublicIP()
for i := 0; i < 3; i++ { if err != nil {
return err
}
var w sync.WaitGroup
// Run loop 2 times
for i := 0; i < 2; i++ {
// Gets information from IP table // Gets information from IP table
//Addresses, err = p2p.ReadIpTable() Addresses, err = p2p.ReadIpTable()
//if err != nil { if err != nil {
// return err return err
//} }
//
//DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP) //DoNotRead.IpAddress = append(DoNotRead.IpAddress, PublicIP)
// Updates IP table based on server IP table // Updates IP table based on server IP table
for j := range Addresses.IpAddress { for j := range Addresses.IpAddress {
//Exists := false Exists := false
// // If the address is local then add to the local list
//if PublicIP.Ipv4 == Addresses.IpAddress[j].Ipv4 || (PublicIP.Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == PublicIP.Ipv6){ if currentIPV4 == Addresses.IpAddress[j].Ipv4 && Addresses.IpAddress[j].ServerPort == Config.ServerPort {
// Exists = true Exists = true
//} }
//
//// Check if IP addresses is there in the struct DoNotRead
//for k := range DoNotRead.IpAddress {
// if DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) {
// Exists = true
// break
// }
//}
//
//// If the struct exists then continues
//if Exists {
// continue
//}
// Check if IP addresses is there in the struct DoNotRead
for k := range DoNotRead.IpAddress {
if (DoNotRead.IpAddress[k].Ipv4 == Addresses.IpAddress[j].Ipv4 && DoNotRead.IpAddress[k].ServerPort == Addresses.IpAddress[j].ServerPort) || (DoNotRead.IpAddress[k].Ipv6 != "" && Addresses.IpAddress[j].Ipv6 == DoNotRead.IpAddress[k].Ipv6) {
Exists = true
break
}
}
// If the struct exists then continues
if Exists {
continue
}
w.Add(1)
if Addresses.IpAddress[j].Ipv6 != "" { if Addresses.IpAddress[j].Ipv6 != "" {
err = UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort) go UpdateIpTable(Addresses.IpAddress[j].Ipv6, Addresses.IpAddress[j].ServerPort, &w)
} else { } else if Addresses.IpAddress[j].Ipv4 != currentIPV4 {
err = UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort) go UpdateIpTable(Addresses.IpAddress[j].Ipv4, Addresses.IpAddress[j].ServerPort, &w)
}
if err != nil {
return err
} }
w.Wait()
//Appends server1 IP address to variable DoNotRead //Appends server1 IP address to variable DoNotRead
//DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j]) DoNotRead.IpAddress = append(DoNotRead.IpAddress, Addresses.IpAddress[j])
} }
} }
@@ -234,4 +252,3 @@ func UploadMultipartFile(client http.Client, uri, key, path string) ([]byte, err
return content, nil return content, nil
} }

View File

@@ -1,4 +1,4 @@
package client package clientIPTable
import ( import (
"testing" "testing"
@@ -11,4 +11,3 @@ func TestUpdateIpTableListClient(t *testing.T) {
t.Error(err) t.Error(err)
} }
} }

View File

@@ -3,8 +3,8 @@ package client
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strconv" "strconv"
@@ -12,39 +12,39 @@ import (
var ( var (
serverPort = "8088" serverPort = "8088"
client = http.Client{} client = http.Client{}
) )
// StartContainer Start container using REST api Implementation // StartContainer Start container using REST api Implementation
// From the selected server IP address // From the selected server IP address
// TODO: Test cases for this function // TODO: Test cases for this function
//Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd // Calls URL ex: http://0.0.0.0:8088/startcontainer?ports=0&GPU=false&ContainerName=docker-ubuntu-sshd
func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*docker.DockerVM ,error) { func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*docker.DockerVM, error) {
// Passes URL with number of TCP ports to allocated and to give GPU access to the docker container // Passes URL with number of TCP ports to allocated and to give GPU access to the docker container
var URL string var URL string
version := p2p.Ip4or6(IP) //version := p2p.Ip4or6(IP)
//
////Get port number of the server
//serverPort, err := GetServerPort(IP)
//if err != nil {
// return nil, err
//}
//Get port number of the server //if version == "version 6" {
serverPort, err := GetServerPort(IP) // URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
if err != nil { //} else {
return nil, err URL = "http://" + IP + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
} //}
if version == "version 6" {
URL = "http://[" + IP + "]:" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
} else {
URL = "http://" + IP + ":" + serverPort + "/startcontainer?ports=" + fmt.Sprint(NumPorts) + "&GPU=" + strconv.FormatBool(GPU) + "&ContainerName=" + ContainerName
}
resp, err := http.Get(URL) resp, err := http.Get(URL)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Convert response to byte value // Convert response to byte value
byteValue, err := ioutil.ReadAll(resp.Body) byteValue, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Create variable for result response type // Create variable for result response type
@@ -53,7 +53,7 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*d
// Adds byte value to docker.DockerVM struct // Adds byte value to docker.DockerVM struct
json.Unmarshal(byteValue, &dockerResult) json.Unmarshal(byteValue, &dockerResult)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Adds the container to the tracked list // Adds the container to the tracked list
@@ -66,21 +66,21 @@ func StartContainer(IP string, NumPorts int, GPU bool, ContainerName string) (*d
} }
// RemoveContianer Stops and removes container from the server // RemoveContianer Stops and removes container from the server
func RemoveContianer(IP string,ID string) error { func RemoveContianer(IP string, ID string) error {
var URL string var URL string
version := p2p.Ip4or6(IP) //version := p2p.Ip4or6(IP)
//
////Get port number of the server
//serverPort, err := GetServerPort(IP)
//if err != nil {
// return err
//}
//Get port number of the server //if version == "version 6" {
serverPort, err := GetServerPort(IP) // URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
if err != nil { //} else {
return err URL = "http://" + IP + "/RemoveContainer?id=" + ID
} //}
if version == "version 6" {
URL = "http://[" + IP + "]:" + serverPort + "/RemoveContainer?id=" + ID
} else {
URL = "http://" + IP + ":" + serverPort + "/RemoveContainer?id=" + ID
}
resp, err := http.Get(URL) resp, err := http.Get(URL)
if err != nil { if err != nil {
return err return err
@@ -102,7 +102,7 @@ func RemoveContianer(IP string,ID string) error {
if err != nil { if err != nil {
return err return err
} }
// Remove container created from the tracked list // Remove container created from the tracked list
err = RemoveTrackedContainer(ID) err = RemoveTrackedContainer(ID)
if err != nil { if err != nil {
return err return err
@@ -112,31 +112,31 @@ func RemoveContianer(IP string,ID string) error {
} }
// ViewContainers This function displays all containers available on server side // ViewContainers This function displays all containers available on server side
func ViewContainers(IP string)(*docker.DockerContainers, error){ func ViewContainers(IP string) (*docker.DockerContainers, error) {
// Passes URL with route /ShowImages // Passes URL with route /ShowImages
var URL string var URL string
version := p2p.Ip4or6(IP) //version := p2p.Ip4or6(IP)
//
////Get port number of the server
//serverPort, err := GetServerPort(IP)
//if err != nil {
// return nil, err
//}
//Get port number of the server //if version == "version 6" {
serverPort, err := GetServerPort(IP) // URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
if err != nil { //} else {
return nil, err URL = "http://" + IP + "/ShowImages"
} //}
if version == "version 6" {
URL = "http://[" + IP + "]:" + serverPort + "/ShowImages"
} else {
URL = "http://" + IP + ":" + serverPort + "/ShowImages"
}
resp, err := http.Get(URL) resp, err := http.Get(URL)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Convert response to byte value // Convert response to byte value
byteValue, err := ioutil.ReadAll(resp.Body) byteValue, err := ioutil.ReadAll(resp.Body)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Create variable for result response type // Create variable for result response type
@@ -145,18 +145,18 @@ func ViewContainers(IP string)(*docker.DockerContainers, error){
// Adds byte value to docker.DockerContainers struct // Adds byte value to docker.DockerContainers struct
json.Unmarshal(byteValue, &Result) json.Unmarshal(byteValue, &Result)
if err != nil { if err != nil {
return nil,err return nil, err
} }
return &Result, nil return &Result, nil
} }
// GetServerPort Helper function to do find out server port information // GetServerPort Helper function to do find out server port information
func GetServerPort(IpAddress string) (string,error) { func GetServerPort(IpAddress string) (string, error) {
// Getting information from the clients ip table // Getting information from the clients ip table
ipTable, err := p2p.ReadIpTable() ipTable, err := p2p.ReadIpTable()
if err != nil { if err != nil {
return "",err return "", err
} }
// Iterate thorough ip table struct and find // Iterate thorough ip table struct and find
@@ -170,7 +170,7 @@ func GetServerPort(IpAddress string) (string,error) {
} }
// We return default port // We return default port
return "8088",nil return "8088", nil
} }
// PrintStartContainer Prints results Generated container // PrintStartContainer Prints results Generated container
@@ -187,7 +187,6 @@ func GetServerPort(IpAddress string) (string,error) {
// } // }
//} //}
// TODO implementation using RPC calls // TODO implementation using RPC calls
//func StartContainer(Ip string) (*docker.DockerVM,error){ //func StartContainer(Ip string) (*docker.DockerVM,error){
// client, err := rpc.DialHTTP("tcp",Ip + ":" + serverPort) // client, err := rpc.DialHTTP("tcp",Ip + ":" + serverPort)

View File

@@ -2,25 +2,28 @@ package cmd
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/client" "github.com/Akilan1999/p2p-rendering-computation/client"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
"git.sr.ht/~akilan1999/p2p-rendering-computation/generate" "github.com/Akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/generate"
"git.sr.ht/~akilan1999/p2p-rendering-computation/plugin" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server" "github.com/Akilan1999/p2p-rendering-computation/plugin"
"github.com/Akilan1999/p2p-rendering-computation/server"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
var CliAction = func(ctx *cli.Context) error { var CliAction = func(ctx *cli.Context) error {
if Server { if Server {
// TODO: with RPC calls err := server.Server()
server.Server() if err != nil {
fmt.Print(err)
}
//server.Rpc() //server.Rpc()
} }
//Listing servers and also updates IP tables (Default 3 hops) //Listing servers and also updates IP tables (Default 3 hops)
if UpdateServerList { if UpdateServerList {
err := client.UpdateIpTableListClient() err := clientIPTable.UpdateIpTableListClient()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
@@ -77,7 +80,6 @@ var CliAction = func(ctx *cli.Context) error {
// Adds the new server IP to the iptable // Adds the new server IP to the iptable
res.WriteIpTable() res.WriteIpTable()
} }
// Displays all images available on the server side // Displays all images available on the server side
@@ -91,8 +93,8 @@ var CliAction = func(ctx *cli.Context) error {
} }
// Function called to stop and remove server from Docker // Function called to stop and remove server from Docker
if RemoveVM != "" && ID != "" { if RemoveVM != "" && ID != "" {
err := client.RemoveContianer(RemoveVM,ID) err := client.RemoveContianer(RemoveVM, ID)
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
@@ -109,7 +111,7 @@ var CliAction = func(ctx *cli.Context) error {
} }
// Calls function to do Api call to start the container on the server side // Calls function to do Api call to start the container on the server side
imageRes, err := client.StartContainer(CreateVM,PortsInt,GPU,ContainerName) imageRes, err := client.StartContainer(CreateVM, PortsInt, GPU, ContainerName)
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
@@ -146,9 +148,9 @@ var CliAction = func(ctx *cli.Context) error {
} }
// If the view plugin flag is called then display all // If the view plugin flag is called then display all
// plugins available // plugins available
if ViewPlugin { if ViewPlugin {
plugins ,err := plugin.DetectPlugins() plugins, err := plugin.DetectPlugins()
if err != nil { if err != nil {
fmt.Print(err) fmt.Print(err)
} }
@@ -205,9 +207,9 @@ var CliAction = func(ctx *cli.Context) error {
} else { } else {
client.PrettyPrint(group) client.PrettyPrint(group)
} }
} else if ID != "" { // Add container to group based on group ID provided } else if ID != "" { // Add container to group based on group ID provided
// --id <Container ID> // --id <Container ID>
group, err := client.AddContainerToGroup(ID,Group) group, err := client.AddContainerToGroup(ID, Group)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
} else { } else {
@@ -244,6 +246,16 @@ var CliAction = func(ctx *cli.Context) error {
client.PrettyPrint(groups) client.PrettyPrint(groups)
} }
} }
// Starts server as a reverse proxy so that
// nodes can connect to each other behind NAT
//if FRPProxy {
// err := frp.StartFRPProxyFromRandom()
// if err != nil {
// fmt.Println(err)
// }
//}
// -- REMOVE ON REGULAR RELEASE -- // -- REMOVE ON REGULAR RELEASE --
// when flag --gen is called an extension // when flag --gen is called an extension
// of the project is created to repurpose // of the project is created to repurpose
@@ -252,9 +264,9 @@ var CliAction = func(ctx *cli.Context) error {
var err error var err error
// If the module name is provided // If the module name is provided
if Modulename != "" { if Modulename != "" {
err = generate.GenerateNewProject(Generate,Modulename) err = generate.GenerateNewProject(Generate, Modulename)
} else { } else {
err = generate.GenerateNewProject(Generate,Generate) err = generate.GenerateNewProject(Generate, Generate)
} }
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
@@ -288,7 +300,5 @@ var CliAction = func(ctx *cli.Context) error {
} }
} }
return nil return nil
} }

View File

@@ -6,223 +6,231 @@ import (
// Variables declared for CLI // Variables declared for CLI
var ( var (
AddServer string AddServer string
ViewImages string ViewImages string
CreateVM string CreateVM string
ContainerName string ContainerName string
Ports string Ports string
Server bool Server bool
RemoveVM string RemoveVM string
ID string ID string
Specs string Specs string
GPU bool GPU bool
UpdateServerList bool UpdateServerList bool
ServerList bool ServerList bool
SetDefaultConfig bool SetDefaultConfig bool
NetworkInterface bool NetworkInterface bool
ViewPlugin bool ViewPlugin bool
TrackedContainers bool TrackedContainers bool
ExecutePlugin string ExecutePlugin string
CreateGroup bool CreateGroup bool
Group string Group string
Groups bool Groups bool
RemoveContainerGroup bool RemoveContainerGroup bool
RemoveGroup string RemoveGroup string
//FRPProxy bool
// Generate only allowed in dev release // Generate only allowed in dev release
// -- REMOVE ON REGULAR RELEASE -- // -- REMOVE ON REGULAR RELEASE --
Generate string Generate string
Modulename string Modulename string
//-------------------------------- //--------------------------------
PullPlugin string PullPlugin string
RemovePlugin string RemovePlugin string
) )
var AppConfigFlags = []cli.Flag{ var AppConfigFlags = []cli.Flag{
// Deprecated to be implemented using GRPC // Deprecated to be implemented using GRPC
&cli.BoolFlag{ &cli.BoolFlag{
Name: "Server", Name: "Server",
Aliases: []string{"s"}, Aliases: []string{"s"},
Usage: "Starts server", Usage: "Starts server",
EnvVars: []string{"SERVER"}, EnvVars: []string{"SERVER"},
Destination: &Server, Destination: &Server,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "UpdateServerList", Name: "UpdateServerList",
Aliases: []string{"us"}, Aliases: []string{"us"},
Usage: "Update List of Server available based on servers iptables", Usage: "Update List of Server available based on servers iptables",
EnvVars: []string{"UPDATE_SERVER_LIST"}, EnvVars: []string{"UPDATE_SERVER_LIST"},
Destination: &UpdateServerList, Destination: &UpdateServerList,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "ListServers", Name: "ListServers",
Aliases: []string{"ls"}, Aliases: []string{"ls"},
Usage: "List servers which can render tasks", Usage: "List servers which can render tasks",
EnvVars: []string{"LIST_SERVERS"}, EnvVars: []string{"LIST_SERVERS"},
Destination: &ServerList, Destination: &ServerList,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "AddServer", Name: "AddServer",
Aliases: []string{"as"}, Aliases: []string{"as"},
Usage: "Adds server IP address to iptables", Usage: "Adds server IP address to iptables",
EnvVars: []string{"ADD_SERVER"}, EnvVars: []string{"ADD_SERVER"},
Destination: &AddServer, Destination: &AddServer,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "ViewImages", Name: "ViewImages",
Aliases: []string{"vi"}, Aliases: []string{"vi"},
Usage: "View images available on the server IP address", Usage: "View images available on the server IP address",
EnvVars: []string{"VIEW_IMAGES"}, EnvVars: []string{"VIEW_IMAGES"},
Destination: &ViewImages, Destination: &ViewImages,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "CreateVM", Name: "CreateVM",
Aliases: []string{"touch"}, Aliases: []string{"touch"},
Usage: "Creates Docker container on the selected server", Usage: "Creates Docker container on the selected server",
EnvVars: []string{"CREATE_VM"}, EnvVars: []string{"CREATE_VM"},
Destination: &CreateVM, Destination: &CreateVM,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "ContainerName", Name: "ContainerName",
Aliases: []string{"cn"}, Aliases: []string{"cn"},
Usage: "Specifying the container run on the server side", Usage: "Specifying the container run on the server side",
EnvVars: []string{"CONTAINER_NAME"}, EnvVars: []string{"CONTAINER_NAME"},
Destination: &ContainerName, Destination: &ContainerName,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "RemoveVM", Name: "RemoveVM",
Aliases: []string{"rm"}, Aliases: []string{"rm"},
Usage: "Stop and Remove Docker container", Usage: "Stop and Remove Docker container",
EnvVars: []string{"REMOVE_VM"}, EnvVars: []string{"REMOVE_VM"},
Destination: &RemoveVM, Destination: &RemoveVM,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "ID", Name: "ID",
Aliases: []string{"id"}, Aliases: []string{"id"},
Usage: "Docker Container ID", Usage: "Docker Container ID",
EnvVars: []string{"ID"}, EnvVars: []string{"ID"},
Destination: &ID, Destination: &ID,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "Ports", Name: "Ports",
Aliases: []string{"p"}, Aliases: []string{"p"},
Usage: "Number of ports to open for the Docker Container", Usage: "Number of ports to open for the Docker Container",
EnvVars: []string{"NUM_PORTS"}, EnvVars: []string{"NUM_PORTS"},
Destination: &Ports, Destination: &Ports,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "GPU", Name: "GPU",
Aliases: []string{"gpu"}, Aliases: []string{"gpu"},
Usage: "Create Docker Containers to access GPU", Usage: "Create Docker Containers to access GPU",
EnvVars: []string{"USE_GPU"}, EnvVars: []string{"USE_GPU"},
Destination: &GPU, Destination: &GPU,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "Specification", Name: "Specification",
Aliases: []string{"specs"}, Aliases: []string{"specs"},
Usage: "Specs of the server node", Usage: "Specs of the server node",
EnvVars: []string{"SPECS"}, EnvVars: []string{"SPECS"},
Destination: &Specs, Destination: &Specs,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "SetDefaultConfig", Name: "SetDefaultConfig",
Aliases: []string{"dc"}, Aliases: []string{"dc"},
Usage: "Sets a default configuration file", Usage: "Sets a default configuration file",
EnvVars: []string{"SET_DEFAULT_CONFIG"}, EnvVars: []string{"SET_DEFAULT_CONFIG"},
Destination: &SetDefaultConfig, Destination: &SetDefaultConfig,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "NetworkInterfaces", Name: "NetworkInterfaces",
Aliases: []string{"ni"}, Aliases: []string{"ni"},
Usage: "Shows the network interface in your computer", Usage: "Shows the network interface in your computer",
EnvVars: []string{"NETWORK_INTERFACE"}, EnvVars: []string{"NETWORK_INTERFACE"},
Destination: &NetworkInterface, Destination: &NetworkInterface,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "ViewPlugins", Name: "ViewPlugins",
Aliases: []string{"vp"}, Aliases: []string{"vp"},
Usage: "Shows plugins available to be executed", Usage: "Shows plugins available to be executed",
EnvVars: []string{"VIEW_PLUGIN"}, EnvVars: []string{"VIEW_PLUGIN"},
Destination: &ViewPlugin, Destination: &ViewPlugin,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "TrackedContainers", Name: "TrackedContainers",
Aliases: []string{"tc"}, Aliases: []string{"tc"},
Usage: "View containers which have " + Usage: "View containers which have " +
"been created from the client side ", "been created from the client side ",
EnvVars: []string{"TRACKED_CONTAINERS"}, EnvVars: []string{"TRACKED_CONTAINERS"},
Destination: &TrackedContainers, Destination: &TrackedContainers,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "ExecutePlugin", Name: "ExecutePlugin",
Aliases: []string{"plugin"}, Aliases: []string{"plugin"},
Usage: "Plugin which needs to be executed", Usage: "Plugin which needs to be executed",
EnvVars: []string{"EXECUTE_PLUGIN"}, EnvVars: []string{"EXECUTE_PLUGIN"},
Destination: &ExecutePlugin, Destination: &ExecutePlugin,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "CreateGroup", Name: "CreateGroup",
Aliases: []string{"cgroup"}, Aliases: []string{"cgroup"},
Usage: "Creates a new group", Usage: "Creates a new group",
EnvVars: []string{"CREATE_GROUP"}, EnvVars: []string{"CREATE_GROUP"},
Destination: &CreateGroup, Destination: &CreateGroup,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "Group", Name: "Group",
Aliases: []string{"group"}, Aliases: []string{"group"},
Usage: "group flag with argument group ID", Usage: "group flag with argument group ID",
EnvVars: []string{"GROUP"}, EnvVars: []string{"GROUP"},
Destination: &Group, Destination: &Group,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "Groups", Name: "Groups",
Aliases: []string{"groups"}, Aliases: []string{"groups"},
Usage: "View all groups", Usage: "View all groups",
EnvVars: []string{"GROUPS"}, EnvVars: []string{"GROUPS"},
Destination: &Groups, Destination: &Groups,
}, },
&cli.BoolFlag{ &cli.BoolFlag{
Name: "RemoveContainerGroup", Name: "RemoveContainerGroup",
Aliases: []string{"rmcgroup"}, Aliases: []string{"rmcgroup"},
Usage: "Remove specific container in the group", Usage: "Remove specific container in the group",
EnvVars: []string{"REMOVE_CONTAINER_GROUP"}, EnvVars: []string{"REMOVE_CONTAINER_GROUP"},
Destination: &RemoveContainerGroup, Destination: &RemoveContainerGroup,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "RemoveGroup", Name: "RemoveGroup",
Aliases: []string{"rmgroup"}, Aliases: []string{"rmgroup"},
Usage: "Removes the entire group", Usage: "Removes the entire group",
EnvVars: []string{"REMOVE_GROUP"}, EnvVars: []string{"REMOVE_GROUP"},
Destination: &RemoveGroup, Destination: &RemoveGroup,
}, },
// Generate only allowed in dev release // Generate only allowed in dev release
// -- REMOVE ON REGULAR RELEASE -- // -- REMOVE ON REGULAR RELEASE --
&cli.StringFlag{ &cli.StringFlag{
Name: "Generate", Name: "Generate",
Aliases: []string{"gen"}, Aliases: []string{"gen"},
Usage: "Generates a new copy of P2PRC which can be modified based on your needs", Usage: "Generates a new copy of P2PRC which can be modified based on your needs",
EnvVars: []string{"GENERATE"}, EnvVars: []string{"GENERATE"},
Destination: &Generate, Destination: &Generate,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "ModuleName", Name: "ModuleName",
Aliases: []string{"mod"}, Aliases: []string{"mod"},
Usage: "New go project module name", Usage: "New go project module name",
EnvVars: []string{"MODULENAME"}, EnvVars: []string{"MODULENAME"},
Destination: &Modulename, Destination: &Modulename,
}, },
//&cli.BoolFlag{
// Name: "FRPServerProxy",
// Aliases: []string{"proxy"},
// Usage: "Starts proxy for server",
// EnvVars: []string{"FRPSERVERPROXY"},
// Destination: &FRPProxy,
//},
//-------------------------------- //--------------------------------
&cli.StringFlag{ &cli.StringFlag{
Name: "PullPlugin", Name: "PullPlugin",
Aliases: []string{"pp"}, Aliases: []string{"pp"},
Usage: "Pulls plugin from git repos", Usage: "Pulls plugin from git repos",
EnvVars: []string{"PULLPLUGIN"}, EnvVars: []string{"PULLPLUGIN"},
Destination: &PullPlugin, Destination: &PullPlugin,
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "RemovePlugin", Name: "RemovePlugin",
Aliases: []string{"rp"}, Aliases: []string{"rp"},
Usage: "Removes plugin", Usage: "Removes plugin",
EnvVars: []string{"REMOVEPLUGIN"}, EnvVars: []string{"REMOVEPLUGIN"},
Destination: &RemovePlugin, Destination: &RemovePlugin,
}, },
} }

View File

@@ -7,25 +7,28 @@ import (
) )
var ( var (
defaultPath string defaultPath string
defaults = map[string]interface{}{} defaults = map[string]interface{}{}
configName = "config" configName = "config"
configType = "json" configType = "json"
configFile = "config.json" configFile = "config.json"
configPaths []string configPaths []string
defaultEnvName = "P2PRC" defaultEnvName = "P2PRC"
) )
type Config struct { type Config struct {
IPTable string MachineName string
DockerContainers string IPTable string
DefaultDockerFile string DockerContainers string
SpeedTestFile string DefaultDockerFile string
IPV6Address string SpeedTestFile string
PluginPath string IPV6Address string
TrackContainersPath string PluginPath string
ServerPort string TrackContainersPath string
ServerPort string
GroupTrackContainersPath string GroupTrackContainersPath string
FRPServerPort string
BehindNAT string
//NetworkInterface string //NetworkInterface string
//NetworkInterfaceIPV6Index int //NetworkInterfaceIPV6Index int
} }
@@ -64,7 +67,7 @@ func Copy(src, dst string) error {
} }
// GetPathP2PRC Getting P2PRC Directory from environment variable // GetPathP2PRC Getting P2PRC Directory from environment variable
func GetPathP2PRC()(string,error) { func GetPathP2PRC() (string, error) {
curDir := os.Getenv(defaultEnvName) curDir := os.Getenv(defaultEnvName)
return curDir + "/", nil return curDir + "/", nil
} }
@@ -80,40 +83,38 @@ func SetEnvName(EnvName string) error {
} }
// GetCurrentPath Getting P2PRC Directory from environment variable // GetCurrentPath Getting P2PRC Directory from environment variable
func GetCurrentPath()(string,error) { func GetCurrentPath() (string, error) {
curDir := os.Getenv("PWD") curDir := os.Getenv("PWD")
return curDir + "/", nil return curDir + "/", nil
} }
// SetDefaults This function to be called only during a // SetDefaults This function to be called only during a
// make install // make install
func SetDefaults() error { func SetDefaults() error {
//Setting current directory to default path //Setting current directory to default path
defaultPath, err := GetPathP2PRC() defaultPath, err := GetPathP2PRC()
if err != nil{ if err != nil {
return err return err
} }
//Creates ip_table.json in the json directory //Creates ip_table.json in the json directory
err = Copy("p2p/ip_table.json","p2p/iptable/ip_table.json") err = Copy("p2p/ip_table.json", "p2p/iptable/ip_table.json")
if err != nil { if err != nil {
return err return err
} }
//Creates a copy of trackcontainers.json in the appropriate directory //Creates a copy of trackcontainers.json in the appropriate directory
err = Copy("client/trackcontainers.json","client/trackcontainers/trackcontainers.json") err = Copy("client/trackcontainers.json", "client/trackcontainers/trackcontainers.json")
if err != nil { if err != nil {
return err return err
} }
//Creates a copy of trackcontainers.json in the appropriate directory //Creates a copy of trackcontainers.json in the appropriate directory
err = Copy("client/grouptrackcontainers.json","client/trackcontainers/grouptrackcontainers.json") err = Copy("client/grouptrackcontainers.json", "client/trackcontainers/grouptrackcontainers.json")
if err != nil { if err != nil {
return err return err
} }
//Setting default paths for the config file //Setting default paths for the config file
defaults["IPTable"] = defaultPath + "p2p/iptable/ip_table.json" defaults["IPTable"] = defaultPath + "p2p/iptable/ip_table.json"
defaults["DefaultDockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/" defaults["DefaultDockerFile"] = defaultPath + "server/docker/containers/docker-ubuntu-sshd/"
@@ -124,6 +125,15 @@ func SetDefaults() error {
defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json" defaults["TrackContainersPath"] = defaultPath + "client/trackcontainers/trackcontainers.json"
defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json" defaults["GroupTrackContainersPath"] = defaultPath + "client/trackcontainers/grouptrackcontainers.json"
defaults["ServerPort"] = "8088" defaults["ServerPort"] = "8088"
defaults["FRPServerPort"] = "0"
defaults["BehindNAT"] = "True"
// Random name generator
hostname, err := os.Hostname()
if err != nil {
return err
}
defaults["MachineName"] = hostname
//defaults["NetworkInterface"] = "wlp0s20f3" //defaults["NetworkInterface"] = "wlp0s20f3"
//defaults["NetworkInterfaceIPV6Index"] = "2" //defaults["NetworkInterfaceIPV6Index"] = "2"
@@ -145,18 +155,18 @@ func SetDefaults() error {
return nil return nil
} }
func ConfigInit()(*Config,error) { func ConfigInit() (*Config, error) {
//Setting current directory to default path //Setting current directory to default path
defaultPath, err := GetPathP2PRC() defaultPath, err := GetPathP2PRC()
if err != nil{ if err != nil {
return nil, err return nil, err
} }
//Paths to search for config file //Paths to search for config file
configPaths = append(configPaths, defaultPath) configPaths = append(configPaths, defaultPath)
//Add all possible configurations paths //Add all possible configurations paths
for _,v := range configPaths { for _, v := range configPaths {
viper.AddConfigPath(v) viper.AddConfigPath(v)
} }
@@ -164,23 +174,23 @@ func ConfigInit()(*Config,error) {
if err := viper.ReadInConfig(); err != nil { if err := viper.ReadInConfig(); err != nil {
// If the error thrown is config file not found // If the error thrown is config file not found
//Sets default configuration to viper //Sets default configuration to viper
for k,v := range defaults { for k, v := range defaults {
viper.SetDefault(k,v) viper.SetDefault(k, v)
} }
viper.SetConfigName(configName) viper.SetConfigName(configName)
viper.SetConfigFile(configFile) viper.SetConfigFile(configFile)
viper.SetConfigType(configType) viper.SetConfigType(configType)
if err = viper.WriteConfig(); err != nil { if err = viper.WriteConfig(); err != nil {
return nil,err return nil, err
} }
} }
// Adds configuration to the struct // Adds configuration to the struct
var config Config var config Config
if err := viper.Unmarshal(&config); err != nil { if err := viper.Unmarshal(&config); err != nil {
return nil,err return nil, err
} }
return &config,nil return &config, nil
} }

View File

View File

@@ -4,7 +4,7 @@ package generate
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/otiai10/copy" "github.com/otiai10/copy"
"go/ast" "go/ast"
"go/token" "go/token"
@@ -17,15 +17,15 @@ import (
// NewProject Struct information required when creating a new project // NewProject Struct information required when creating a new project
type NewProject struct { type NewProject struct {
Name string Name string
Module string Module string
NewDir string NewDir string
P2PRCPath string P2PRCPath string
CurrentModule string CurrentModule string
Option *copy.Options Option *copy.Options
Token *token.FileSet Token *token.FileSet
AST *ast.File AST *ast.File
FileNameAST string FileNameAST string
} }
// GenerateNewProject creates a new copy of the P2PRC // GenerateNewProject creates a new copy of the P2PRC

View File

@@ -2,7 +2,7 @@ package generate
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"testing" "testing"
) )
@@ -19,7 +19,7 @@ func TestCreateFolder(t *testing.T) {
// Testing if a new project is created successfully // Testing if a new project is created successfully
func TestGenerateNewProject(t *testing.T) { func TestGenerateNewProject(t *testing.T) {
// Checking if a new project is created successfully // Checking if a new project is created successfully
err := GenerateNewProject("p2prctest","p2prctest") err := GenerateNewProject("p2prctest", "p2prctest")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Error(err) t.Error(err)
@@ -29,7 +29,7 @@ func TestGenerateNewProject(t *testing.T) {
// Testing AST function to ensure imports are // Testing AST function to ensure imports are
// working as intended // working as intended
func TestChangingImportAST(t *testing.T) { func TestChangingImportAST(t *testing.T) {
// Create a new variable of type NewProject // Create a new variable of type NewProject
var np NewProject var np NewProject
// Get current directory // Get current directory
path, err := config.GetCurrentPath() path, err := config.GetCurrentPath()
@@ -38,7 +38,7 @@ func TestChangingImportAST(t *testing.T) {
t.Error(err) t.Error(err)
} }
// Create testcase scenario // Create testcase scenario
err = config.Copy(path + "testcaseAST.go", path + "/Test/testcaseAST.go") err = config.Copy(path+"testcaseAST.go", path+"/Test/testcaseAST.go")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Error(err) t.Error(err)
@@ -109,4 +109,4 @@ func TestNewProject_GetCurrentGoModule(t *testing.T) {
t.Error(err) t.Error(err)
} }
fmt.Println(np.CurrentModule) fmt.Println(np.CurrentModule)
} }

19
go.mod
View File

@@ -1,35 +1,30 @@
module git.sr.ht/~akilan1999/p2p-rendering-computation module github.com/Akilan1999/p2p-rendering-computation
go 1.15 go 1.15
require ( require (
github.com/Microsoft/hcsshim v0.8.15 // indirect github.com/Microsoft/hcsshim v0.8.15 // indirect
github.com/StackExchange/wmi v0.0.0-20190523213315-cbe66965904d // indirect
github.com/apenella/go-ansible v1.1.0 github.com/apenella/go-ansible v1.1.0
github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect github.com/containerd/continuity v0.0.0-20210315143101-93e15499afd5 // indirect
github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible github.com/docker/docker v20.10.0-beta1.0.20201113105859-b6bfff2a628f+incompatible
github.com/docker/go-connections v0.4.0 github.com/docker/go-connections v0.4.0
github.com/fatedier/frp v0.45.0
github.com/gin-gonic/gin v1.6.3 github.com/gin-gonic/gin v1.6.3
github.com/go-git/go-git/v5 v5.4.2 github.com/go-git/go-git/v5 v5.4.2
github.com/go-ole/go-ole v1.2.5 // indirect github.com/google/uuid v1.3.0
github.com/google/go-cmp v0.5.4 // indirect github.com/goombaio/namegenerator v0.0.0-20181006234301-989e774b106e
github.com/google/uuid v1.1.2
github.com/gorilla/mux v1.8.0 // indirect
github.com/lithammer/shortuuid v3.0.0+incompatible github.com/lithammer/shortuuid v3.0.0+incompatible
github.com/moby/sys/mount v0.2.0 // indirect github.com/moby/sys/mount v0.2.0 // indirect
github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect github.com/moby/term v0.0.0-20201110203204-bea5bbe245bf // indirect
github.com/morikuni/aec v1.0.0 // indirect github.com/morikuni/aec v1.0.0 // indirect
github.com/otiai10/copy v1.6.0 github.com/otiai10/copy v1.6.0
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2 github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2
github.com/shirou/gopsutil v3.20.12+incompatible github.com/shirou/gopsutil/v3 v3.22.10
github.com/spf13/viper v1.4.0 github.com/spf13/viper v1.7.0
github.com/urfave/cli/v2 v2.3.0 github.com/urfave/cli/v2 v2.3.0
gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect gitlab.com/NebulousLabs/fastrand v0.0.0-20181126182046-603482d69e40 // indirect
gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3 gitlab.com/NebulousLabs/go-upnp v0.0.0-20181011194642-3a71999ed0d3
golang.org/x/mod v0.3.0 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4
golang.org/x/text v0.3.5 // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
google.golang.org/grpc v1.35.0 // indirect
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
gotest.tools/v3 v3.0.3 // indirect gotest.tools/v3 v3.0.3 // indirect
) )

521
go.sum

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +0,0 @@
<html>
<head>
<title>P2PRC</title>
<style>
body { font-family: sans-serif; }
</style>
</head>
<body>
<img src="Docs/images/p2prclogo.png" alt="P2PRC Logo">
<h1>P2PRC</h1>
<b>A peer to peer network designed for computation</b>
<p><dfn>P2PRC</dfn> is peer to peer to network designed for computation reasons.</p>
<p>This project was developed during my 4th year dissertation at Heriot-Watt University and We are getting the
project to a usable state.</p>
<p> It's purpose is for people to use each others computers rather than servers such as <abbr title="Amazon Web Services">AWS</abbr> and <span title="Microsoft Azure">Azure</span>.</p>
<p><b>Project:</b></p>
<ul>
<li>
<a href="https://github.com/Akilan1999/p2p-rendering-computation" target="_blank">P2PRC on GitHub</a>
</li>
<li>
<a href="https://discord.gg/b4nRGTjYqy" target="_blank">P2PRC Discord Server</a> <span style="color: red;">(join here to chat!)</span>
</li>
</ul>
<p><b>Community Server to download public network</b></p>
<ul>
<li>
<b>Only for v1.0.0</b>
<br>
<!-- <b>IP Address: 172.104.44.195</b>-->
<p>Use this server to only download part of the p2p network</p>
</li>
<li>
<b>Master branch</b>
<br>
<!-- <b>IP Address: 139.162.246.221</b>-->
<p>Use this server to only download part of the p2p network</p>
</li>
</ul>
<p><b>Main developer:</b></p>
<ul>
<li>
<b><a href="https://akilan.io" target="_blank"><span title="The Not So Boring Developer">Akilan Selvacoumar</span></a></b>
</li>
</ul>
<p><b>Other links:</b></p>
<ul>
<li><a href="https://www.youtube.com/channel/UChy18QB1hBzZ7MniIW_FJvQ" target="_blank">Akilan Selvacoumar on YouTube</a></li>
<li><a href="https://akilan.io/projects/p2prc/" target="_blank">Project info from akilan.io</a></li>
</ul>
</body>
</html>

View File

@@ -1,7 +1,7 @@
package main package main
import ( import (
"git.sr.ht/~akilan1999/p2p-rendering-computation/cmd" "github.com/Akilan1999/p2p-rendering-computation/cmd"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
"log" "log"
"os" "os"
@@ -12,7 +12,7 @@ var VERSION = "1.5.0"
var mode string var mode string
// Varaibles if mode is client // Varaibles if mode is client
var OS, Pull_location ,Run_script string var OS, Pull_location, Run_script string
var List_servers, Ip_table bool var List_servers, Ip_table bool
func main() { func main() {
@@ -27,4 +27,4 @@ func main() {
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
} }

165
p2p/frp/client.go Normal file
View File

@@ -0,0 +1,165 @@
package frp
import (
"fmt"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/fatedier/frp/client"
"github.com/fatedier/frp/pkg/config"
"github.com/phayes/freeport"
"math/rand"
"strconv"
"time"
)
// Client This struct stores
// client information with server
// proxy connected
type Client struct {
Name string
Server *Server
ClientMappings []ClientMapping
}
// ClientMapping Stores client mapping ports
// to proxy server
type ClientMapping struct {
LocalIP string
LocalPort int
RemotePort int
}
// StartFRPClientForServer Starts Server using FRP server
// returns back a port
func StartFRPClientForServer(ipaddress string, port string, localport string) (string, error) {
// Setup server information
var s Server
s.address = ipaddress
// convert port to int
portInt, err := strconv.Atoi(port)
if err != nil {
return "", err
}
s.port = portInt
// Setup client information
var c Client
c.Name = "ServerPort"
c.Server = &s
// converts localport to int
portInt, err = strconv.Atoi(localport)
if err != nil {
return "", err
}
//random port
//randPort := rangeIn(10000, 99999)
OpenPorts, err := freeport.GetFreePorts(1)
if err != nil {
return "", err
}
c.ClientMappings = []ClientMapping{
{
LocalIP: "localhost",
LocalPort: portInt,
RemotePort: OpenPorts[0],
},
}
// Start client server
go c.StartFRPClient()
return strconv.Itoa(OpenPorts[0]), nil
}
func StartFRPCDockerContainer(ipaddress string, port string, Docker *docker.DockerVM) (*docker.DockerVM, error) {
// setting new docker variable
//var DockerFRP docker.DockerVM
//DockerFRP = *Docker
//DockerFRP.Ports.PortSet = []docker.Port{}
// Setup server information
var s Server
s.address = ipaddress
// convert port to int
portInt, err := strconv.Atoi(port)
if err != nil {
return nil, err
}
s.port = portInt
// Setup client information
var c Client
c.Name = "ServerPort"
c.Server = &s
// set client mapping
//var clientMappings []ClientMapping
fmt.Println(len(Docker.Ports.PortSet))
for i, _ := range Docker.Ports.PortSet {
portMap := Docker.Ports.PortSet[i].ExternalPort
serverPort, err := GetFRPServerPort("http://" + ipaddress + ":" + port)
if err != nil {
return nil, err
}
//delay to allow the FRP server to start
time.Sleep(1 * time.Second)
proxyPort, err := StartFRPClientForServer(ipaddress, serverPort, strconv.Itoa(portMap))
if err != nil {
return nil, err
}
portInt, err = strconv.Atoi(proxyPort)
if err != nil {
return nil, err
}
Docker.Ports.PortSet[i].ExternalPort = portInt
}
return Docker, nil
}
// StartFRPClient Starts FRP client
func (c *Client) StartFRPClient() error {
cfg := config.GetDefaultClientConf()
var proxyConfs map[string]config.ProxyConf
var visitorCfgs map[string]config.VisitorConf
proxyConfs = make(map[string]config.ProxyConf)
cfg.ServerAddr = c.Server.address
cfg.ServerPort = c.Server.port
for i, _ := range c.ClientMappings {
var tcpcnf config.TCPProxyConf
tcpcnf.LocalIP = c.ClientMappings[i].LocalIP
tcpcnf.LocalPort = c.ClientMappings[i].LocalPort
tcpcnf.RemotePort = c.ClientMappings[i].RemotePort
proxyConfs[tcpcnf.ProxyName] = &tcpcnf
}
cli, err := client.NewService(cfg, proxyConfs, visitorCfgs, "")
if err != nil {
return err
}
cli.Run()
return nil
}
// helper function to generate random
// number in a certain range
func rangeIn(low, hi int) int {
return low + rand.Intn(hi-low)
}

81
p2p/frp/server.go Normal file
View File

@@ -0,0 +1,81 @@
package frp
import (
"github.com/fatedier/frp/pkg/config"
"github.com/fatedier/frp/server"
"github.com/phayes/freeport"
"io/ioutil"
"net/http"
)
type Server struct {
address string
port int
}
// StartFRPProxyFromRandom starts
// reverse proxy server based on
// a random port generated
func StartFRPProxyFromRandom() (int, error) {
// gets current configuration
//config, err := configP2PRC.ConfigInit()
//if err != nil {
// return err
//}
var s Server
s.address = "0.0.0.0"
// use random port
OpenPorts, err := freeport.GetFreePorts(1)
if err != nil {
return 0, err
}
s.port = OpenPorts[0]
// start FRP server
go s.StartFRPServer()
return OpenPorts[0], nil
}
// StartFRPServer The initial plan is only support reverse proxy
// for TCP ports
// This function starts a server that can act as a reverse
// proxy for nodes behind NAT.
func (s *Server) StartFRPServer() error {
baseConfig := config.GetDefaultServerConf()
baseConfig.BindAddr = s.address
baseConfig.BindPort = s.port
service, err := server.NewService(baseConfig)
if err != nil {
return err
}
service.Run()
return nil
}
// GetFRPServerPort Gets the port no from the FRPServer to establish
// the FRP connection needed.
func GetFRPServerPort(host string) (string, error) {
resp, err := http.Get(host + "/FRPPort")
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
return string(body), nil
}

46
p2p/frp/server_test.go Normal file
View File

@@ -0,0 +1,46 @@
package frp
import (
"fmt"
"testing"
"time"
)
// Testing scenario FRPServer
func TestStartFRPServer(t *testing.T) {
var s Server
s.address = "127.0.0.1"
s.port = 8808
err := s.StartFRPServer()
if err != nil {
fmt.Println(err)
t.Fail()
}
}
// Testing scenario FRPServer and FRPClient connection
func TestStartFRPClient(t *testing.T) {
var s Server
s.address = "127.0.0.1"
s.port = 8808
go s.StartFRPServer()
time.Sleep(3 * time.Second)
// Sample test client
var c Client
c.Server = &s
c.ClientMappings = []ClientMapping{
{
LocalIP: "127.0.0.1",
LocalPort: 22,
RemotePort: 3301,
},
}
err := c.StartFRPClient()
if err != nil {
fmt.Println(err)
t.Fail()
}
}

View File

@@ -1,12 +1,13 @@
{ {
"ip_address": [ "ip_address": [
{ {
"ipv4": "139.162.246.221", "Name": "Node1",
"ipv6": "", "IPV4": "64.227.168.102",
"latency": 0, "IPV6": "",
"download": 0, "Latency": 0,
"upload": 0, "ServerPort": "8088",
"serverport": "8088" "NAT": "False",
"EscapeImplementation": "None"
} }
] ]
} }

View File

@@ -3,7 +3,7 @@ package p2p
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"io/ioutil" "io/ioutil"
"net" "net"
"net/http" "net/http"
@@ -18,12 +18,15 @@ type IpAddresses struct {
} }
type IpAddress struct { type IpAddress struct {
Ipv4 string `json:"ipv4"` Name string `json:"Name"`
Ipv6 string `json:"ipv6"` Ipv4 string `json:"IPV4"`
Latency time.Duration `json:"latency"` Ipv6 string `json:"IPV6"`
Download float64 `json:"download"` Latency time.Duration `json:"Latency"`
Upload float64 `json:"upload"` Download float64 `json:"Download"`
ServerPort string `json:"serverport"` Upload float64 `json:"Upload"`
ServerPort string `json:"ServerPort"`
NAT string `json:"NAT"`
EscapeImplementation string `json:"EscapeImplementation"`
} }
type IP struct { type IP struct {
@@ -31,19 +34,18 @@ type IP struct {
} }
// ReadIpTable Read data from Ip tables from json file // ReadIpTable Read data from Ip tables from json file
func ReadIpTable()(*IpAddresses ,error){ func ReadIpTable() (*IpAddresses, error) {
// Get Path from config // Get Path from config
config, err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return nil,err return nil, err
} }
jsonFile, err := os.Open(config.IPTable) jsonFile, err := os.Open(config.IPTable)
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return nil,err return nil, err
} }
// defer the closing of our jsonFile so that we can parse it later on // defer the closing of our jsonFile so that we can parse it later on
defer jsonFile.Close() defer jsonFile.Close()
@@ -71,6 +73,9 @@ func ReadIpTable()(*IpAddresses ,error){
PublicIP.Ipv4 = ip PublicIP.Ipv4 = ip
PublicIP.Ipv6 = ipv6 PublicIP.Ipv6 = ipv6
PublicIP.ServerPort = config.ServerPort PublicIP.ServerPort = config.ServerPort
PublicIP.Name = config.MachineName
PublicIP.NAT = config.BehindNAT
PublicIP.EscapeImplementation = "None"
// Updates current machine IP address to the IP table // Updates current machine IP address to the IP table
ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP) ipAddresses.IpAddress = append(ipAddresses.IpAddress, PublicIP)
@@ -80,7 +85,7 @@ func ReadIpTable()(*IpAddresses ,error){
return nil, err return nil, err
} }
return &ipAddresses, nil return &ipAddresses, nil
} }
// WriteIpTable Write to IP table json file // WriteIpTable Write to IP table json file
@@ -118,27 +123,39 @@ func PrintIpTable() error {
} }
for i := 0; i < len(table.IpAddress); i++ { for i := 0; i < len(table.IpAddress); i++ {
fmt.Printf("\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\n-----------" + fmt.Printf("\nMachine Name: %s\nIP Address: %s\nIPV6: %s\nLatency: %s\nServerPort: %s\nbehindNAT: %s\nEscapeImplementation: %s\n-----------"+
"-----------------\n",table.IpAddress[i].Ipv4,table.IpAddress[i].Ipv6, "-----------------\n", table.IpAddress[i].Name, table.IpAddress[i].Ipv4, table.IpAddress[i].Ipv6,
table.IpAddress[i].Latency, table.IpAddress[i].ServerPort) table.IpAddress[i].Latency, table.IpAddress[i].ServerPort, table.IpAddress[i].NAT, table.IpAddress[i].EscapeImplementation)
} }
//PrettyPrint(table)
return nil return nil
} }
// RemoveDuplicates This is a temporary fix current functions failing to remove // RemoveDuplicates This is a temporary fix current functions failing to remove
// Duplicate IP addresses from local IP table // Duplicate IP addresses from local IP table
func (table *IpAddresses)RemoveDuplicates() error { func (table *IpAddresses) RemoveDuplicates() error {
var NoDuplicates IpAddresses var NoDuplicates IpAddresses
for i, _:= range table.IpAddress { for i, _ := range table.IpAddress {
Exists := false Exists := false
for k := range NoDuplicates.IpAddress { for k := range NoDuplicates.IpAddress {
if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4) || (NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) { // Statements checked for
// - duplicate IPV4 addresses [<IPV4>:<Port No>]
// - duplicate IPV6 addresses [<IPV6>]
// - Node is behind NAT and no escape implementation provided
if (NoDuplicates.IpAddress[k].Ipv4 != "" && NoDuplicates.IpAddress[k].Ipv4 == table.IpAddress[i].Ipv4 &&
NoDuplicates.IpAddress[k].ServerPort == table.IpAddress[i].ServerPort) ||
(NoDuplicates.IpAddress[k].Ipv6 != "" && NoDuplicates.IpAddress[k].Ipv6 == table.IpAddress[i].Ipv6) {
Exists = true Exists = true
break break
} }
} }
if table.IpAddress[i].NAT == "True" && table.IpAddress[i].EscapeImplementation == "None" {
Exists = true
}
if Exists { if Exists {
continue continue
} }
@@ -151,16 +168,16 @@ func (table *IpAddresses)RemoveDuplicates() error {
} }
// CurrentPublicIP Get Current Public IP address // CurrentPublicIP Get Current Public IP address
func CurrentPublicIP() (string,error) { func CurrentPublicIP() (string, error) {
req, err := http.Get("http://ip-api.com/json/") req, err := http.Get("http://ip-api.com/json/")
if err != nil { if err != nil {
return "",err return "", err
} }
defer req.Body.Close() defer req.Body.Close()
body, err := ioutil.ReadAll(req.Body) body, err := ioutil.ReadAll(req.Body)
if err != nil { if err != nil {
return "",err return "", err
} }
var ip IP var ip IP
@@ -171,10 +188,10 @@ func CurrentPublicIP() (string,error) {
// GetCurrentIPV6 gets the current IPV6 address based on the interface // GetCurrentIPV6 gets the current IPV6 address based on the interface
// specified in the config file // specified in the config file
func GetCurrentIPV6()(string,error){ func GetCurrentIPV6() (string, error) {
Config, err := config.ConfigInit() Config, err := config.ConfigInit()
if err != nil { if err != nil {
return "",err return "", err
} }
// Fix in future release // Fix in future release
@@ -223,7 +240,7 @@ func ViewNetworkInterface() error {
} }
// Ip4or6 Helper function to check if the IP address is IPV4 or // Ip4or6 Helper function to check if the IP address is IPV4 or
//IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6) // IPV6 (https://socketloop.com/tutorials/golang-check-if-ip-address-is-version-4-or-6)
func Ip4or6(s string) string { func Ip4or6(s string) string {
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
switch s[i] { switch s[i] {
@@ -235,4 +252,15 @@ func Ip4or6(s string) string {
} }
return "version 6" return "version 6"
} }
//func PrettyPrint(data interface{}) {
// var p []byte
// // var err := error
// p, err := json.MarshalIndent(data, "", "\t")
// if err != nil {
// fmt.Println(err)
// return
// }
// fmt.Printf("%s \n", p)
//}

View File

View File

@@ -1,12 +1,12 @@
package p2p package p2p
// SpeedTest Runs a speed test and does updates IP tables accordingly // SpeedTest Runs a speed test and does updates IP tables accordingly
func (ip *IpAddresses)SpeedTest() error{ func (ip *IpAddresses) SpeedTest() error {
//temp variable to store elements IP addresses and other information //temp variable to store elements IP addresses and other information
// of IP addresses that are pingable // of IP addresses that are pingable
var ActiveIP IpAddresses var ActiveIP IpAddresses
// Index to remove from struct // Index to remove from struct
for _, value := range ip.IpAddress { for _, value := range ip.IpAddress {
@@ -36,7 +36,6 @@ func (ip *IpAddresses)SpeedTest() error{
//Set value to the list //Set value to the list
ActiveIP.IpAddress = append(ActiveIP.IpAddress, value) ActiveIP.IpAddress = append(ActiveIP.IpAddress, value)
} }
ip.IpAddress = ActiveIP.IpAddress ip.IpAddress = ActiveIP.IpAddress
@@ -50,7 +49,7 @@ func (ip *IpAddresses)SpeedTest() error{
} }
// SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on // SpeedTestUpdatedIPTable Called when ip tables from httpclient/server is also passed on
func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{ func (ip *IpAddresses) SpeedTestUpdatedIPTable() error {
targets, err := ReadIpTable() targets, err := ReadIpTable()
if err != nil { if err != nil {
return err return err
@@ -59,24 +58,24 @@ func (ip *IpAddresses)SpeedTestUpdatedIPTable() error{
// To ensure struct has no duplicates IP addresses // To ensure struct has no duplicates IP addresses
//DoNotRead := targets //DoNotRead := targets
// Appends all IP addresses // Appends all IP addresses
for i, _ := range targets.IpAddress { for i, _ := range targets.IpAddress {
// To ensure that there are no duplicate IP addresses //To ensure that there are no duplicate IP addresses
//Exists := false Exists := false
//for k := range ip.IpAddress { for k := range ip.IpAddress {
// // Checks if both the IPV4 addresses are the same or the IPV6 address is not // Checks if both the IPV4 addresses are the same or the IPV6 address is not
// // an empty string and IPV6 address are the same // an empty string and IPV6 address are the same
// if ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) { if (ip.IpAddress[k].Ipv4 == targets.IpAddress[i].Ipv4 && targets.IpAddress[i].NAT == "True") || (targets.IpAddress[i].Ipv6 != "" && ip.IpAddress[k].Ipv6 == targets.IpAddress[i].Ipv6) {
// Exists = true Exists = true
// break break
// } }
//} }
//
//// If the struct exists then continues // If the struct exists then continues
//if Exists { if Exists {
// continue continue
//} }
ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i]) ip.IpAddress = append(ip.IpAddress, targets.IpAddress[i])
} }
@@ -105,7 +104,6 @@ func LocalSpeedTestIpTable() error {
return nil return nil
} }
// Helper function to remove element from an array of a struct // Helper function to remove element from an array of a struct
//func remove(s []IpAddress, i int) []IpAddress { //func remove(s []IpAddress, i int) []IpAddress {
// s[len(s)-1], s[i] = s[i], s[len(s)-1] // s[len(s)-1], s[i] = s[i], s[len(s)-1]

View File

@@ -2,7 +2,8 @@ package p2p
import ( import (
"bytes" "bytes"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "errors"
"github.com/Akilan1999/p2p-rendering-computation/config"
"io" "io"
"io/ioutil" "io/ioutil"
"log" "log"
@@ -12,8 +13,8 @@ import (
"time" "time"
) )
//var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000} // var dlSizes = [...]int{350, 500, 750, 1000, 1500, 2000, 2500, 3000, 3500, 4000}
//var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB // var ulSizes = [...]int{100, 300, 500, 800, 1000, 1500, 2500, 3000, 3500, 4000} //kB
var httpclient = http.Client{} var httpclient = http.Client{}
// DownloadTest executes the test to measure download speed // DownloadTest executes the test to measure download speed
@@ -78,7 +79,7 @@ var httpclient = http.Client{}
//} //}
// Download Speed // Download Speed
func (s *IpAddress)DownloadSpeed() error { func (s *IpAddress) DownloadSpeed() error {
start := time.Now() start := time.Now()
resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50") resp, err := httpclient.Get("http://" + s.Ipv4 + ":8088/50")
if err != nil { if err != nil {
@@ -89,11 +90,11 @@ func (s *IpAddress)DownloadSpeed() error {
t := time.Since(start) t := time.Since(start)
//fmt.Println(s.Seconds()) //fmt.Println(s.Seconds())
// size * time (seconds) // size * time (seconds)
s.Download = (50/t.Seconds())*8 s.Download = (50 / t.Seconds()) * 8
return nil return nil
} }
func (s *IpAddress)UploadSpeed() error { func (s *IpAddress) UploadSpeed() error {
start := time.Now() start := time.Now()
// Get upload file path from config file // Get upload file path from config file
@@ -103,9 +104,9 @@ func (s *IpAddress)UploadSpeed() error {
return err return err
} }
b, w := createMultipartFormData("file",config.SpeedTestFile) b, w := createMultipartFormData("file", config.SpeedTestFile)
req, err := http.NewRequest("GET", "http://" + s.Ipv4 + ":" + s.ServerPort + "/upload", &b) req, err := http.NewRequest("GET", "http://"+s.Ipv4+":"+s.ServerPort+"/upload", &b)
if err != nil { if err != nil {
return err return err
} }
@@ -116,12 +117,12 @@ func (s *IpAddress)UploadSpeed() error {
t := time.Since(start) t := time.Since(start)
//fmt.Println(s.Seconds()) //fmt.Println(s.Seconds())
// size * time (seconds) // size * time (seconds)
s.Upload = (50/t.Seconds())*8 s.Upload = (50 / t.Seconds()) * 8
return nil return nil
} }
//Upload helper function for uploading // Upload helper function for uploading
//(https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data // (https://stackoverflow.com/questions/20205796/post-data-using-the-content-type-multipart-form-data
func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) { func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipart.Writer) {
var b bytes.Buffer var b bytes.Buffer
var err error var err error
@@ -142,7 +143,7 @@ func createMultipartFormData(fieldName, fileName string) (bytes.Buffer, *multipa
func mustOpen(f string) *os.File { func mustOpen(f string) *os.File {
r, err := os.Open(f) r, err := os.Open(f)
if err != nil { if err != nil {
log.Fatalf("Error with mustOpen: %v",err) log.Fatalf("Error with mustOpen: %v", err)
} }
return r return r
} }
@@ -163,8 +164,8 @@ func (s *IpAddress) PingTest() error {
sTime := time.Now() sTime := time.Now()
resp, err := http.Get(pingURL) resp, err := http.Get(pingURL)
fTime := time.Now() fTime := time.Now()
if err != nil { if err != nil || resp.StatusCode != 200 {
return err return errors.New("Node not found")
} }
if fTime.Sub(sTime) < l { if fTime.Sub(sTime) < l {
l = fTime.Sub(sTime) l = fTime.Sub(sTime)
@@ -176,4 +177,3 @@ func (s *IpAddress) PingTest() error {
return nil return nil
} }

View File

@@ -1,76 +1,74 @@
package p2p package p2p
import ( import (
"fmt" "fmt"
"gitlab.com/NebulousLabs/go-upnp" "gitlab.com/NebulousLabs/go-upnp"
) )
// Port forwarding to the router // Port forwarding to the router
func ForwardPort(port int) error{ func ForwardPort(port int) error {
// connect to router // connect to router
d, err := upnp.Discover() d, err := upnp.Discover()
if err != nil { if err != nil {
return err return err
} }
// discover external IP // discover external IP
ip, err := d.ExternalIP() ip, err := d.ExternalIP()
if err != nil { if err != nil {
return err return err
} }
fmt.Println("Your external IP is:", ip) fmt.Println("Your external IP is:", ip)
// forward a port // forward a port
err = d.Forward(50498, "upnp test") err = d.Forward(50498, "upnp test")
if err != nil { if err != nil {
return err return err
} }
// record router's location // record router's location
loc := d.Location() loc := d.Location()
// connect to router directly // connect to router directly
d, err = upnp.Load(loc) d, err = upnp.Load(loc)
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }
// unForwardPort from router // UnForwardPort from router
func UnForwardPort(port int) error{ func UnForwardPort(port int) error {
// connect to router // connect to router
d, err := upnp.Discover() d, err := upnp.Discover()
if err != nil { if err != nil {
return err return err
} }
// discover external IP
ip, err := d.ExternalIP()
if err != nil {
return err
}
// discover external IP fmt.Println("Your external IP is:", ip)
ip, err := d.ExternalIP()
if err != nil {
return err
}
fmt.Println("Your external IP is:", ip) // un-forward a port
err = d.Clear(50498)
if err != nil {
return err
}
// record router's location
loc := d.Location()
// un-forward a port // connect to router directly
err = d.Clear(50498) d, err = upnp.Load(loc)
if err != nil { if err != nil {
return err return err
} }
// record router's location return nil
loc := d.Location()
// connect to router directly
d, err = upnp.Load(loc)
if err != nil {
return err
}
return nil
} }

15
p2p/upnp_test.go Normal file
View File

@@ -0,0 +1,15 @@
package p2p
import (
"fmt"
"testing"
)
// Tests if the current has UPNP support
func TestForwardUPNPPort(t *testing.T) {
err := ForwardPort(6586)
if err != nil {
fmt.Println(err)
t.Fail()
}
}

View File

@@ -1,102 +1 @@
# Laplace
Laplace is an open-source project to enable screen sharing directly via browser.
Made possible using WebRTC for low latency peer-to-peer connections, and WebSocket implemented in golang for WebRTC signaling.
> Demo video: https://youtu.be/E8cUaPrAlzE
[![Laplace for gaming](./doc/laplace-for-gaming.png)](https://youtu.be/E8cUaPrAlzE)
## Try Demo
For demo, you can visit https://laplace.madeby.monster/
![Website screenshot](./doc/screenshot-website.png)
## Motivation
There are already possible solutions to share your computer screen, e.g. TeamViewer.
But most of them require installations of software or plugins.
What Laplace provides is a simple solution to this problem.
For users wanting to share their screen, all they need to do is to open a website page with their browsers, clicking some buttons, then share some session ID with their peers.
No installation or registration required.
#### Solving the latency problem
This project also serves as a proof-of-concept (PoC) for screen sharing capability directly in browsers based on WebRTC.
Using WebRTC, real-time communication is made possible through peer-to-peer connections.
This proves to be very useful in solving one of the biggest problems is screen streaming: **Latency**.
The latency represents how long the delay is from the source to transmit to the remote client.
If you notice, this latency problem is usually highlighted by game streaming services, since gameplay relies heavily on the interactivity of inputs and outputs.
#### Low server cost
This solution also solves the server cost problem, since the expensive operations (encoding and transmission) are done on client browsers.
The server is only needed for serving frontends and for WebRTC signaling.
#### Possible Use Cases
- Game streaming from PC to mobile devices.
- Collaborative work where you need to share your screen with remote coworkers.
- Mirroring presentation slides and demonstrations.
## Installation
Build from source
```bash
$ git clone https://github.com/adamyordan/laplace.git
$ cd laplace && go build -o laplace main.go
$ ./laplace --help
```
OR, pull the pre-built docker image
```bash
$ docker pull adamyordan/laplace
$ docker run adamyordan/laplace ./laplace --help
```
## Program Execution
Executing this project basically serves an HTTP server that will host the frontend and the WebSocket implementation.
Note that you sometimes need to run HTTPs in order for browser to connect to websocket.
```bash
$ ./laplace --help
-addr string
Listen address (default "0.0.0.0:443")
-certFile string
TLS cert file (default "files/server.crt")
-keyFile string
TLS key file (default "files/server.key")
-tls
Use TLS (default true)
```
By default, you can run the executable without any argument to listen to TLS port 443.
A self-signed certificate files are provided to ease up development.
```bash
$ ./laplace
2020/03/25 01:01:10 Listening on TLS: 0.0.0.0:443
```
You can then open https://localhost:443/ to view Laplace page.
You may need to add certificate exceptions. In Chrome, you can type `thisisunsafe`.
## Contributing
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
## License
[MIT](https://choosealicense.com/licenses/mit/)

View File

@@ -1,7 +1,7 @@
package plugin package plugin
import ( import (
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"net/url" "net/url"
"os" "os"
@@ -29,7 +29,7 @@ func DownloadPlugin(pluginurl string) error {
return err return err
} }
// clones a repo and stores it at the plugin directory // clones a repo and stores it at the plugin directory
_, err = git.PlainClone(config.PluginPath + "/" + folder, false, &git.CloneOptions{ _, err = git.PlainClone(config.PluginPath+"/"+folder, false, &git.CloneOptions{
URL: pluginurl, URL: pluginurl,
Progress: os.Stdout, Progress: os.Stdout,
}) })
@@ -38,7 +38,6 @@ func DownloadPlugin(pluginurl string) error {
return err return err
} }
return nil return nil
} }
@@ -60,6 +59,6 @@ func DeletePlugin(pluginname string) error {
if err != nil { if err != nil {
return err return err
} }
return nil return nil
} }

View File

@@ -5,11 +5,12 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/client" "github.com/Akilan1999/p2p-rendering-computation/client"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/google/uuid" "github.com/google/uuid"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
"io/ioutil" "io/ioutil"
"net"
"os" "os"
"strconv" "strconv"
"text/template" "text/template"
@@ -28,11 +29,11 @@ type Plugins struct {
// Plugin Information about the plugins available // Plugin Information about the plugins available
type Plugin struct { type Plugin struct {
FolderName string FolderName string
PluginDescription string PluginDescription string
path string path string
Execute []*ExecuteIP Execute []*ExecuteIP
NumOfPorts int NumOfPorts int
} }
// ExecuteIP IP Address to execute Ansible instruction // ExecuteIP IP Address to execute Ansible instruction
@@ -40,7 +41,7 @@ type ExecuteIP struct {
ContainerID string ContainerID string
IPAddress string IPAddress string
SSHPortNo string SSHPortNo string
Success bool Success bool
} }
// Host Struct for ansible host // Host Struct for ansible host
@@ -65,52 +66,52 @@ type Host struct {
} }
// DetectPlugins Detects all the plugins available // DetectPlugins Detects all the plugins available
func DetectPlugins()(*Plugins,error){ func DetectPlugins() (*Plugins, error) {
config, err:= config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return nil,err return nil, err
} }
folders, err := ioutil.ReadDir(config.PluginPath) folders, err := ioutil.ReadDir(config.PluginPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
var plugins *Plugins = new(Plugins) var plugins *Plugins = new(Plugins)
for _, f := range folders { for _, f := range folders {
if f.IsDir() { if f.IsDir() {
//Declare variable plugin of type Plugin //Declare variable plugin of type Plugin
var plugin Plugin var plugin Plugin
// Setting name of folder to plugin // Setting name of folder to plugin
plugin.FolderName = f.Name() plugin.FolderName = f.Name()
// Getting Description from file description.txt // Getting Description from file description.txt
Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt") Description, err := ioutil.ReadFile(config.PluginPath + "/" + plugin.FolderName + "/description.txt")
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
return nil, err return nil, err
} }
// Get Description from description.txt // Get Description from description.txt
plugin.PluginDescription = string(Description) plugin.PluginDescription = string(Description)
// Set plugin path // Set plugin path
plugin.path = config.PluginPath + "/" + plugin.FolderName plugin.path = config.PluginPath + "/" + plugin.FolderName
plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin) plugins.PluginsDetected = append(plugins.PluginsDetected, &plugin)
// Get the number of ports the plugin needs // Get the number of ports the plugin needs
err = plugin.NumPorts() err = plugin.NumPorts()
if err != nil { if err != nil {
return nil, err return nil, err
}
} }
} }
}
return plugins,nil return plugins, nil
} }
// SearchPlugin Detects plugin information based on the // SearchPlugin Detects plugin information based on the
// name provided on the parameter // name provided on the parameter
func SearchPlugin(pluginname string) (*Plugin,error) { func SearchPlugin(pluginname string) (*Plugin, error) {
plugins, err := DetectPlugins() plugins, err := DetectPlugins()
if err != nil { if err != nil {
return nil, err return nil, err
@@ -127,15 +128,15 @@ func SearchPlugin(pluginname string) (*Plugin,error) {
} }
// RunPlugin Executes plugins based on the plugin name provided // RunPlugin Executes plugins based on the plugin name provided
func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) { func RunPlugin(pluginName string, IPAddresses []*ExecuteIP) (*Plugin, error) {
plugins, err := DetectPlugins() plugins, err := DetectPlugins()
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Variable to store struct information about the plugin // Variable to store struct information about the plugin
var plugindetected *Plugin var plugindetected *Plugin
for _,plugin := range plugins.PluginsDetected { for _, plugin := range plugins.PluginsDetected {
if plugin.FolderName == pluginName { if plugin.FolderName == pluginName {
plugindetected = plugin plugindetected = plugin
plugindetected.Execute = IPAddresses plugindetected.Execute = IPAddresses
@@ -152,8 +153,7 @@ func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) {
if plugindetected == nil { if plugindetected == nil {
return nil, errors.New("Plugin not detected") return nil, errors.New("Plugin not detected")
} }
// Create copy of the plugin the tmp directory // Create copy of the plugin the tmp directory
// To ensure we execute the plugin from there // To ensure we execute the plugin from there
err = plugindetected.CopyToTmpPlugin() err = plugindetected.CopyToTmpPlugin()
@@ -162,19 +162,19 @@ func RunPlugin(pluginName string ,IPAddresses []*ExecuteIP) (*Plugin,error) {
} }
// Executing the plugin // Executing the plugin
err = plugindetected.ExecutePlugin() err = plugindetected.ExecutePlugin()
if err != nil { if err != nil {
return nil,err return nil, err
} }
return plugindetected,nil return plugindetected, nil
} }
// ExecutePlugin Function to execute plugins that are called // ExecutePlugin Function to execute plugins that are called
func (p *Plugin) ExecutePlugin() error { func (p *Plugin) ExecutePlugin() error {
// Run ip address to execute ansible inside // Run ip address to execute ansible inside
for _,execute := range p.Execute { for _, execute := range p.Execute {
// Modify ansible hosts before executing // Modify ansible hosts before executing
err := execute.ModifyHost(p) err := execute.ModifyHost(p)
if err != nil { if err != nil {
@@ -196,18 +196,18 @@ func (p *Plugin) ExecutePlugin() error {
} }
// RunAnsible Executes based on credentials on the struct // RunAnsible Executes based on credentials on the struct
func (e *ExecuteIP)RunAnsible(p *Plugin) error { func (e *ExecuteIP) RunAnsible(p *Plugin) error {
ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{ ansiblePlaybookConnectionOptions := &options.AnsibleConnectionOptions{
User: "master", User: "master",
} }
ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{ ansiblePlaybookOptions := &playbook.AnsiblePlaybookOptions{
Inventory: p.path + "/" + p.FolderName + "/hosts", Inventory: p.path + "/" + p.FolderName + "/hosts",
ExtraVars: map[string]interface{}{"host_key_checking":"false"}, ExtraVars: map[string]interface{}{"ansible_ssh_common_args": "-o StrictHostKeyChecking=no"},
} }
ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{ ansiblePlaybookPrivilegeEscalationOptions := &options.AnsiblePrivilegeEscalationOptions{
Become: true, Become: true,
} }
playbook := &playbook.AnsiblePlaybookCmd{ playbook := &playbook.AnsiblePlaybookCmd{
@@ -231,12 +231,12 @@ func (e *ExecuteIP)RunAnsible(p *Plugin) error {
} }
// ModifyHost adds IP address , port no to the config file // ModifyHost adds IP address , port no to the config file
func (e *ExecuteIP)ModifyHost(p *Plugin) error { func (e *ExecuteIP) ModifyHost(p *Plugin) error {
host,err := ReadHost(p.path + "/" + p.FolderName + "/hosts") host, err := ReadHost(p.path + "/" + p.FolderName + "/hosts")
if err != nil { if err != nil {
return err return err
} }
// Setting ansible host // Setting ansible host
host.Main.Hosts.Host1.AnsibleHost = e.IPAddress host.Main.Hosts.Host1.AnsibleHost = e.IPAddress
// Setting SSH port no // Setting SSH port no
host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo) host.Main.Hosts.Host1.AnsiblePort, err = strconv.Atoi(e.SSHPortNo)
@@ -251,11 +251,11 @@ func (e *ExecuteIP)ModifyHost(p *Plugin) error {
host.Main.Hosts.Host1.AnsibleSudoPass = "password" host.Main.Hosts.Host1.AnsibleSudoPass = "password"
// write modified information to the hosts yaml file // write modified information to the hosts yaml file
data,err := yaml.Marshal(host) data, err := yaml.Marshal(host)
if err != nil { if err != nil {
return err return err
} }
err = ioutil.WriteFile(p.path + "/" + p.FolderName + "/hosts",data,0777) err = ioutil.WriteFile(p.path+"/"+p.FolderName+"/hosts", data, 0777)
if err != nil { if err != nil {
return err return err
} }
@@ -292,7 +292,7 @@ func RunPluginContainer(PluginName string, ContainerID string) error {
var ExecuteIPs []*ExecuteIP var ExecuteIPs []*ExecuteIP
var ExecuteIP ExecuteIP var ExecuteIP ExecuteIP
// Getting port no of SSH port // Getting port no of SSH port
for _,port := range ContainerInformation.Container.Ports.PortSet { for _, port := range ContainerInformation.Container.Ports.PortSet {
if port.PortName == "SSH" { if port.PortName == "SSH" {
ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort) ExecuteIP.SSHPortNo = fmt.Sprint(port.ExternalPort)
break break
@@ -302,14 +302,22 @@ func RunPluginContainer(PluginName string, ContainerID string) error {
if ExecuteIP.SSHPortNo == "" { if ExecuteIP.SSHPortNo == "" {
return errors.New("SSH port not found") return errors.New("SSH port not found")
} }
// IP address of the container // Split the port no from ip address since current the IP address
ExecuteIP.IPAddress = ContainerInformation.IpAddress // field is populated as
// <ip address>:<port no>
host, _, err := net.SplitHostPort(ContainerInformation.IpAddress)
if err != nil {
return err
}
// IP address of the container
ExecuteIP.IPAddress = host
// Set container ID to ExecutorIP // Set container ID to ExecutorIP
ExecuteIP.ContainerID = ContainerInformation.Id ExecuteIP.ContainerID = ContainerInformation.Id
// Append IP to list of executor IP // Append IP to list of executor IP
ExecuteIPs = append(ExecuteIPs, &ExecuteIP) ExecuteIPs = append(ExecuteIPs, &ExecuteIP)
// Run plugin to execute plugin // Run plugin to execute plugin
_, err = RunPlugin(PluginName,ExecuteIPs) _, err = RunPlugin(PluginName, ExecuteIPs)
if err != nil { if err != nil {
return err return err
} }
@@ -355,11 +363,11 @@ func CheckRunPlugin(PluginName string, ID string) error {
// plugin in the tmp directory, and it would be executed // plugin in the tmp directory, and it would be executed
// from there. This due to the reason of automating port allocation // from there. This due to the reason of automating port allocation
// when running plugins // when running plugins
func (p *Plugin)CopyToTmpPlugin() error { func (p *Plugin) CopyToTmpPlugin() error {
// generate rand to UUID this is debug the ansible file if needed // generate rand to UUID this is debug the ansible file if needed
id := uuid.New() id := uuid.New()
// copies the plugin to the tmp directory // copies the plugin to the tmp directory
err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+ id.String() + "_" + p.FolderName) err := copy.Copy(p.path+"/"+p.FolderName, "/tmp/"+id.String()+"_"+p.FolderName)
if err != nil { if err != nil {
return err return err
} }
@@ -368,12 +376,12 @@ func (p *Plugin)CopyToTmpPlugin() error {
p.path = "/tmp" p.path = "/tmp"
p.FolderName = id.String() + "_" + p.FolderName p.FolderName = id.String() + "_" + p.FolderName
return nil return nil
} }
// AutoSetPorts Automatically maps free ports to site.yml file // AutoSetPorts Automatically maps free ports to site.yml file
func (p *Plugin)AutoSetPorts(containerID string) error { func (p *Plugin) AutoSetPorts(containerID string) error {
container , err := client.GetContainerInformation(containerID) container, err := client.GetContainerInformation(containerID)
if err != nil { if err != nil {
return err return err
} }
@@ -394,22 +402,26 @@ func (p *Plugin)AutoSetPorts(containerID string) error {
container.Container.Ports.PortSet[i].IsUsed = true container.Container.Ports.PortSet[i].IsUsed = true
// Incrementing the variable PortTaken // Incrementing the variable PortTaken
PortTaken++ PortTaken++
ports = append(ports, port.ExternalPort) // Maps to internal since
// Inside the machine
// internal port -> (maps) same internal port
// TURN (i.e FRP) based approach (internal port -> maps to different external port)
ports = append(ports, port.InternalPort)
} }
} }
// parses the site.yml file in the tmp directory // parses the site.yml file in the tmp directory
t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml") t, err := template.ParseFiles(p.path + "/" + p.FolderName + "/site.yml")
if err != nil { if err != nil {
return err return err
} }
// opens the output file // opens the output file
f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml") f, err := os.Create(p.path + "/" + p.FolderName + "/site.yml")
if err != nil { if err != nil {
return err return err
} }
// sends the ports to the site.yml file to populate them // sends the ports to the site.yml file to populate them
err = t.Execute(f,ports) err = t.Execute(f, ports)
if err != nil { if err != nil {
return err return err
} }
@@ -431,7 +443,7 @@ func (p *Plugin)AutoSetPorts(containerID string) error {
// NumPorts Gets the Number the ports the // NumPorts Gets the Number the ports the
// plugin requires // plugin requires
func (p *Plugin)NumPorts() error { func (p *Plugin) NumPorts() error {
jsonFile, err := os.Open(p.path + "/ports.json") jsonFile, err := os.Open(p.path + "/ports.json")
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {

View File

@@ -2,9 +2,10 @@ package plugin
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/client" "github.com/Akilan1999/p2p-rendering-computation/client"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"net"
"strconv" "strconv"
"testing" "testing"
) )
@@ -20,10 +21,10 @@ func TestDetectPlugins(t *testing.T) {
// Test ensures that the ansible are executed inside local containers // Test ensures that the ansible are executed inside local containers
func TestRunPlugin(t *testing.T) { func TestRunPlugin(t *testing.T) {
var testips []*ExecuteIP var testips []*ExecuteIP
var testip1,testip2 ExecuteIP var testip1, testip2 ExecuteIP
// Create docker container and get SSH port // Create docker container and get SSH port
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -34,7 +35,7 @@ func TestRunPlugin(t *testing.T) {
testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort) testip1.SSHPortNo = strconv.Itoa(container1.Ports.PortSet[0].ExternalPort)
// Create docker container and get SSH port // Create docker container and get SSH port
container2 ,err := docker.BuildRunContainer(0,"false","") container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -46,7 +47,7 @@ func TestRunPlugin(t *testing.T) {
testips = append(testips, &testip1) testips = append(testips, &testip1)
testips = append(testips, &testip2) testips = append(testips, &testip2)
_,err = RunPlugin("TestAnsible",testips) _, err = RunPlugin("TestAnsible", testips)
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -97,7 +98,7 @@ func TestExecuteIP_ModifyHost(t *testing.T) {
// the test ansible script // the test ansible script
func TestRunPluginContainer(t *testing.T) { func TestRunPluginContainer(t *testing.T) {
// Create docker container and get SSH port // Create docker container and get SSH port
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -136,13 +137,13 @@ func TestRunPluginContainer(t *testing.T) {
// group ID and container ID // group ID and container ID
func TestCheckRunPlugin(t *testing.T) { func TestCheckRunPlugin(t *testing.T) {
// Create docker container and get SSH port // Create docker container and get SSH port
container1 ,err := docker.BuildRunContainer(0,"false","") container1, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
} }
// Create docker container and get SSH port // Create docker container and get SSH port
container2 ,err := docker.BuildRunContainer(0,"false","") container2, err := docker.BuildRunContainer(0, "false", "")
if err != nil { if err != nil {
fmt.Println(err) fmt.Println(err)
t.Fail() t.Fail()
@@ -168,7 +169,6 @@ func TestCheckRunPlugin(t *testing.T) {
t.Fail() t.Fail()
} }
// Add container 1 to the group // Add container 1 to the group
_, err = client.AddContainerToGroup(container1.ID, group.ID) _, err = client.AddContainerToGroup(container1.ID, group.ID)
if err != nil { if err != nil {
@@ -243,4 +243,15 @@ func TestDownloadPlugin(t *testing.T) {
if err != nil { if err != nil {
} }
} }
// Simple test case implemented to the test if
// the port no can be extracted from the IP address.
func TestParseIP(t *testing.T) {
host, port, err := net.SplitHostPort("12.34.23.13:5432")
if err != nil {
fmt.Printf("Error: %v\n", err)
} else {
fmt.Printf("Host: %s\nPort: %s\n", host, port)
}
}

Binary file not shown.

View File

@@ -7,7 +7,7 @@ import (
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/config"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/docker/client" "github.com/docker/docker/client"
@@ -22,21 +22,21 @@ import (
) )
type DockerVM struct { type DockerVM struct {
SSHUsername string `json:"SSHUsername"` SSHUsername string `json:"SSHUsername"`
SSHPassword string `json:"SSHPassword"` SSHPassword string `json:"SSHPassword"`
ID string `json:"ID"` ID string `json:"ID"`
TagName string `json:"TagName"` TagName string `json:"TagName"`
ImagePath string `json:"ImagePath"` ImagePath string `json:"ImagePath"`
Ports Ports `json:"Ports"` Ports Ports `json:"Ports"`
GPU string `json:"GPU"` GPU string `json:"GPU"`
} }
type DockerContainers struct { type DockerContainers struct {
DockerContainer []DockerContainer `json:"DockerContainer"` DockerContainer []DockerContainer `json:"DockerContainer"`
} }
type DockerContainer struct { type DockerContainer struct {
ContainerName string `json:"DockerContainerName"` ContainerName string `json:"DockerContainerName"`
ContainerDescription string `json:"ContainerDescription"` ContainerDescription string `json:"ContainerDescription"`
} }
@@ -44,11 +44,11 @@ type Ports struct {
PortSet []Port `json:"Port"` PortSet []Port `json:"Port"`
} }
type Port struct { type Port struct {
PortName string `json:"PortName"` PortName string `json:"PortName"`
InternalPort int `json:"InternalPort"` InternalPort int `json:"InternalPort"`
Type string `json:"Type"` Type string `json:"Type"`
ExternalPort int `json:"ExternalPort"` ExternalPort int `json:"ExternalPort"`
IsUsed bool `json:"IsUsed"` IsUsed bool `json:"IsUsed"`
Description string `json:"Description"` Description string `json:"Description"`
} }
@@ -65,7 +65,7 @@ var dockerRegistryUserID = ""
// BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external // BuildRunContainer Function is incharge to invoke building and running contianer and also allocating external
// ports // ports
func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerVM,error) { func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerVM, error) {
//Docker Struct Variable //Docker Struct Variable
var RespDocker *DockerVM = new(DockerVM) var RespDocker *DockerVM = new(DockerVM)
@@ -86,7 +86,7 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV
// Get Path from config // Get Path from config
config, err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return nil,err return nil, err
} }
RespDocker.ImagePath = config.DefaultDockerFile RespDocker.ImagePath = config.DefaultDockerFile
@@ -95,7 +95,7 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV
if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" { if ContainerName != "" && ContainerName != "docker-ubuntu-sshd" {
Containers, err := ViewAllContainers() Containers, err := ViewAllContainers()
if err != nil { if err != nil {
return nil,err return nil, err
} }
for _, dockerContainer := range Containers.DockerContainer { for _, dockerContainer := range Containers.DockerContainer {
@@ -106,7 +106,7 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV
} }
} }
if RespDocker.ImagePath == config.DefaultDockerFile { if RespDocker.ImagePath == config.DefaultDockerFile {
return nil, errors.New("Container " + ContainerName + " does not exist in the server") return nil, errors.New("Container " + ContainerName + " does not exist in the server")
} }
} }
@@ -121,7 +121,7 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV
// Creates number of ports // Creates number of ports
OpenPorts, err := freeport.GetFreePorts(count) OpenPorts, err := freeport.GetFreePorts(count)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Allocate external ports to ports available in the ports.json file // Allocate external ports to ports available in the ports.json file
for i := range PortsInformation.PortSet { for i := range PortsInformation.PortSet {
@@ -136,8 +136,8 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV
var TempPort Port var TempPort Port
TempPort.PortName = "AutoGen Port" TempPort.PortName = "AutoGen Port"
TempPort.Type = "tcp" TempPort.Type = "tcp"
TempPort.InternalPort = OpenPorts[portFileLength + i] TempPort.InternalPort = OpenPorts[portFileLength+i]
TempPort.ExternalPort = OpenPorts[portFileLength + i] TempPort.ExternalPort = OpenPorts[portFileLength+i]
TempPort.Description = "Auto generated TCP port" TempPort.Description = "Auto generated TCP port"
TempPort.IsUsed = false TempPort.IsUsed = false
//Append temp port to port information //Append temp port to port information
@@ -149,29 +149,28 @@ func BuildRunContainer(NumPorts int, GPU string, ContainerName string) (*DockerV
// Gets docker information from env variables // Gets docker information from env variables
cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation()) cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Builds docker image // Builds docker image
err = RespDocker.imageBuild(cli) err = RespDocker.imageBuild(cli)
if err != nil { if err != nil {
return nil,err return nil, err
} }
// Runs docker contianer // Runs docker contianer
err = RespDocker.runContainer(cli) err = RespDocker.runContainer(cli)
if err != nil { if err != nil {
return nil,err return nil, err
} }
return RespDocker, nil
return RespDocker,nil
} }
//Builds docker image (TODO: relative path for Dockerfile deploy) // Builds docker image (TODO: relative path for Dockerfile deploy)
func (d *DockerVM)imageBuild(dockerClient *client.Client) error { func (d *DockerVM) imageBuild(dockerClient *client.Client) error {
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000) ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
//defer cancel() //defer cancel()
@@ -203,16 +202,15 @@ func (d *DockerVM)imageBuild(dockerClient *client.Client) error {
// Starts container and assigns port numbers // Starts container and assigns port numbers
// Sample Docker run Command // Sample Docker run Command
// docker run -d=true --name=Test123 --restart=always --gpus all // docker run -d=true --name=Test123 --restart=always --gpus all
//-p 3443:6901 -p 3453:22 -p 3434:3434 -p 3245:3245 -v=/opt/data:/data // -p 3443:6901 -p 3453:22 -p 3434:3434 -p 3245:3245 -v=/opt/data:/data
//p2p-ubuntu /start > /dev/null // p2p-ubuntu /start > /dev/null
func (d *DockerVM)runContainer(dockerClient *client.Client) error{ func (d *DockerVM) runContainer(dockerClient *client.Client) error {
ctx, _ := context.WithTimeout(context.Background(), time.Second*2000) ctx, _ := context.WithTimeout(context.Background(), time.Second*2000)
// The first mode runs using the Docker Api. As the API supports using // The first mode runs using the Docker Api. As the API supports using
// CPU and uses a shell script for GPU call because till this point of // CPU and uses a shell script for GPU call because till this point of
// implementation docker api does not support the flag "--gpu all" // implementation docker api does not support the flag "--gpu all"
if d.GPU != "true" { if d.GPU != "true" {
//Exposed ports for docker config file //Exposed ports for docker config file
var ExposedPort nat.PortSet var ExposedPort nat.PortSet
@@ -239,7 +237,7 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{
for i := range d.Ports.PortSet { for i := range d.Ports.PortSet {
// Parameters "tcp or udp", external port // Parameters "tcp or udp", external port
Port, err := nat.NewPort(d.Ports.PortSet[i].Type,fmt.Sprint(d.Ports.PortSet[i].InternalPort)) Port, err := nat.NewPort(d.Ports.PortSet[i].Type, fmt.Sprint(d.Ports.PortSet[i].InternalPort))
if err != nil { if err != nil {
return err return err
} }
@@ -249,7 +247,7 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{
PortForwarding[Port] = []nat.PortBinding{ PortForwarding[Port] = []nat.PortBinding{
{ {
HostIP: "0.0.0.0", HostIP: "0.0.0.0",
HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort), HostPort: fmt.Sprint(d.Ports.PortSet[i].ExternalPort),
}, },
} }
@@ -286,11 +284,11 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{
d.ID = id d.ID = id
var cmd bytes.Buffer var cmd bytes.Buffer
cmd.WriteString("docker run -d=true --name="+ id +" --restart=always --gpus all ") cmd.WriteString("docker run -d=true --name=" + id + " --restart=always --gpus all ")
for i := range d.Ports.PortSet { for i := range d.Ports.PortSet {
cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ") cmd.WriteString("-p " + fmt.Sprint(d.Ports.PortSet[i].ExternalPort) + ":" + fmt.Sprint(d.Ports.PortSet[i].InternalPort) + " ")
} }
cmd.WriteString("-v=/opt/data:/data "+ d.TagName +" /start > /dev/null") cmd.WriteString("-v=/opt/data:/data " + d.TagName + " /start > /dev/null")
//"-v=/opt/data:/data p2p-ubuntu /start > /dev/null" //"-v=/opt/data:/data p2p-ubuntu /start > /dev/null"
cmdStr := cmd.String() cmdStr := cmd.String()
_, err := exec.Command("/bin/sh", "-c", cmdStr).Output() _, err := exec.Command("/bin/sh", "-c", cmdStr).Output()
@@ -301,7 +299,7 @@ func (d *DockerVM)runContainer(dockerClient *client.Client) error{
return nil return nil
} }
// StopAndRemoveContainer // StopAndRemoveContainer
// Stop and remove a container // Stop and remove a container
// Reference (https://gist.github.com/frikky/e2efcea6c733ea8d8d015b7fe8a91bf6) // Reference (https://gist.github.com/frikky/e2efcea6c733ea8d8d015b7fe8a91bf6)
func StopAndRemoveContainer(containername string) error { func StopAndRemoveContainer(containername string) error {
@@ -330,11 +328,11 @@ func StopAndRemoveContainer(containername string) error {
} }
// ViewAllContainers returns all containers runnable and which can be built // ViewAllContainers returns all containers runnable and which can be built
func ViewAllContainers() (*DockerContainers, error){ func ViewAllContainers() (*DockerContainers, error) {
// Traverse the deploy path as per given in the config file // Traverse the deploy path as per given in the config file
config, err := config.ConfigInit() config, err := config.ConfigInit()
if err != nil { if err != nil {
return nil,err return nil, err
} }
folders, err := ioutil.ReadDir(config.DockerContainers) folders, err := ioutil.ReadDir(config.DockerContainers)
@@ -348,11 +346,11 @@ func ViewAllContainers() (*DockerContainers, error){
for _, f := range folders { for _, f := range folders {
if f.IsDir() { if f.IsDir() {
//Declare variable DockerContainer of type struct //Declare variable DockerContainer of type struct
var Container DockerContainer var Container DockerContainer
// Setting container name to deploy name // Setting container name to deploy name
Container.ContainerName = f.Name() Container.ContainerName = f.Name()
// Getting Description from file description.txt // Getting Description from file description.txt
Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt") Description, err := ioutil.ReadFile(config.DockerContainers + "/" + Container.ContainerName + "/description.txt")
// if we os.Open returns an error then handle it // if we os.Open returns an error then handle it
if err != nil { if err != nil {
@@ -366,7 +364,7 @@ func ViewAllContainers() (*DockerContainers, error){
} }
} }
return Containers,nil return Containers, nil
} }
func print(rd io.Reader) error { func print(rd io.Reader) error {
@@ -403,4 +401,4 @@ func OpenPortsFile(filename string) (*Ports, error) {
} }
return c, nil return c, nil
} }

View File

@@ -1,10 +1,10 @@
package server package server
import ( import (
"github.com/shirou/gopsutil/cpu" "github.com/shirou/gopsutil/v3/cpu"
"github.com/shirou/gopsutil/disk" "github.com/shirou/gopsutil/v3/disk"
"github.com/shirou/gopsutil/host" "github.com/shirou/gopsutil/v3/host"
"github.com/shirou/gopsutil/mem" "github.com/shirou/gopsutil/v3/mem"
) )
// SysInfo saves the basic system information // SysInfo saves the basic system information
@@ -14,22 +14,22 @@ type SysInfo struct {
CPU string `bson:cpu` CPU string `bson:cpu`
RAM uint64 `bson:ram` RAM uint64 `bson:ram`
Disk uint64 `bson:disk` Disk uint64 `bson:disk`
GPU *Query `xml: GpuInfo` GPU *Query `xml: GpuInfo`
} }
func ServerInfo() interface{}{ func ServerInfo() interface{} {
hostStat, _ := host.Info() hostStat, _ := host.Info()
cpuStat, _ := cpu.Info() cpuStat, _ := cpu.Info()
vmStat, _ := mem.VirtualMemory() vmStat, _ := mem.VirtualMemory()
info := new(SysInfo) info := new(SysInfo)
filesystem := "/" filesystem := "/"
// If the server is running windows // If the server is running windows
if info.Hostname == "windows"{ if info.Hostname == "windows" {
filesystem = "\\" filesystem = "\\"
} }
diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/" diskStat, _ := disk.Usage(filesystem) // If you're in Unix change this "\\" for "/"
@@ -39,13 +39,12 @@ func ServerInfo() interface{}{
info.RAM = vmStat.Total / 1024 / 1024 info.RAM = vmStat.Total / 1024 / 1024
info.Disk = diskStat.Total / 1024 / 1024 info.Disk = diskStat.Total / 1024 / 1024
gpu, err := GPUInfo() gpu, err := GPUInfo()
if err == nil { if err == nil {
info.GPU = gpu info.GPU = gpu
} }
return info return info
} }

View File

@@ -2,7 +2,7 @@ package server
import ( import (
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/server/docker"
"net" "net"
"net/rpc" "net/rpc"
) )
@@ -18,8 +18,8 @@ type Docker struct {
} }
// Starts container using RPC calls // Starts container using RPC calls
func (l *Listener) StartContainer( reply *Docker) error { func (l *Listener) StartContainer(reply *Docker) error {
vm, err := docker.BuildRunContainer(3,"false","") vm, err := docker.BuildRunContainer(3, "false", "")
if err != nil { if err != nil {
return err return err
} }
@@ -28,8 +28,6 @@ func (l *Listener) StartContainer( reply *Docker) error {
return nil return nil
} }
func Rpc() { func Rpc() {
rpcServer, err := net.ResolveTCPAddr("tcp", "0.0.0.0:"+port) rpcServer, err := net.ResolveTCPAddr("tcp", "0.0.0.0:"+port)
if err != nil { if err != nil {
@@ -43,4 +41,3 @@ func Rpc() {
rpc.Register(listener) rpc.Register(listener)
rpc.Accept(inbound) rpc.Accept(inbound)
} }

View File

@@ -3,29 +3,39 @@ package server
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"git.sr.ht/~akilan1999/p2p-rendering-computation/config" "github.com/Akilan1999/p2p-rendering-computation/client/clientIPTable"
"git.sr.ht/~akilan1999/p2p-rendering-computation/p2p" "github.com/Akilan1999/p2p-rendering-computation/config"
"git.sr.ht/~akilan1999/p2p-rendering-computation/server/docker" "github.com/Akilan1999/p2p-rendering-computation/p2p"
"github.com/Akilan1999/p2p-rendering-computation/p2p/frp"
"github.com/Akilan1999/p2p-rendering-computation/server/docker"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"strconv"
"time"
) )
func Server() error{ func Server() error {
r := gin.Default() r := gin.Default()
//Get Server port based on the config file
config, err := config.ConfigInit()
if err != nil {
return err
}
// update IPTable with new port and ip address and update ip table
var ProxyIpAddr p2p.IpAddress
var lowestLatencyIpAddress p2p.IpAddress
// Gets default information of the server // Gets default information of the server
r.GET("/server_info", func(c *gin.Context) { r.GET("/server_info", func(c *gin.Context) {
c.JSON(http.StatusOK, ServerInfo()) c.JSON(http.StatusOK, ServerInfo())
}) })
// Speed test with 50 mbps // Speed test with 50 mbps
r.GET("/50", func(c *gin.Context){ r.GET("/50", func(c *gin.Context) {
// Get Path from config // Get Path from config
config, err := config.ConfigInit()
if err != nil {
c.String(http.StatusOK, fmt.Sprint(err))
}
c.File(config.SpeedTestFile) c.File(config.SpeedTestFile)
}) })
@@ -71,7 +81,7 @@ func Server() error{
c.String(http.StatusOK, fmt.Sprint(err)) c.String(http.StatusOK, fmt.Sprint(err))
} }
json.Unmarshal(file,&IPTable) json.Unmarshal(file, &IPTable)
//Add Client IP address to IPTable struct //Add Client IP address to IPTable struct
IPTable.IpAddress = append(IPTable.IpAddress, ClientHost) IPTable.IpAddress = append(IPTable.IpAddress, ClientHost)
@@ -83,7 +93,7 @@ func Server() error{
} }
// Reads IP addresses from ip table // Reads IP addresses from ip table
IpAddresses,err := p2p.ReadIpTable() IpAddresses, err := p2p.ReadIpTable()
if err != nil { if err != nil {
c.String(http.StatusOK, fmt.Sprint(err)) c.String(http.StatusOK, fmt.Sprint(err))
} }
@@ -91,31 +101,40 @@ func Server() error{
c.JSON(http.StatusOK, IpAddresses) c.JSON(http.StatusOK, IpAddresses)
}) })
// Starts docker container in server // Starts docker container in server
r.GET("/startcontainer", func(c *gin.Context) { r.GET("/startcontainer", func(c *gin.Context) {
// Get Number of ports to open and whether to use GPU or not // Get Number of ports to open and whether to use GPU or not
Ports := c.DefaultQuery("ports","0") Ports := c.DefaultQuery("ports", "0")
GPU := c.DefaultQuery("GPU","false") GPU := c.DefaultQuery("GPU", "false")
ContainerName := c.DefaultQuery("ContainerName","") ContainerName := c.DefaultQuery("ContainerName", "")
var PortsInt int var PortsInt int
// Convert Get Request value to int // Convert Get Request value to int
fmt.Sscanf(Ports, "%d", &PortsInt) fmt.Sscanf(Ports, "%d", &PortsInt)
// Creates container and returns-back result to // Creates container and returns-back result to
// access container // access container
resp, err := docker.BuildRunContainer(PortsInt,GPU,ContainerName) resp, err := docker.BuildRunContainer(PortsInt, GPU, ContainerName)
if err != nil { if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
} }
// Ensures that FRP is triggered only if a proxy address is provided
if ProxyIpAddr.Ipv4 != "" && c.Request.Host != "localhost:"+config.ServerPort && c.Request.Host != "0.0.0.0:"+config.ServerPort {
resp, err = frp.StartFRPCDockerContainer(ProxyIpAddr.Ipv4, lowestLatencyIpAddress.ServerPort, resp)
if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
fmt.Println(resp)
}
c.JSON(http.StatusOK, resp) c.JSON(http.StatusOK, resp)
}) })
//Remove container //Remove container
r.GET("/RemoveContainer", func(c *gin.Context) { r.GET("/RemoveContainer", func(c *gin.Context) {
ID := c.DefaultQuery("id","0") ID := c.DefaultQuery("id", "0")
if err := docker.StopAndRemoveContainer(ID); err != nil { if err := docker.StopAndRemoveContainer(ID); err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err)) c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
} }
@@ -131,10 +150,73 @@ func Server() error{
c.JSON(http.StatusOK, resp) c.JSON(http.StatusOK, resp)
}) })
//Get Server port based on the config file // Request for port no from Server with address
config, err := config.ConfigInit() r.GET("/FRPPort", func(c *gin.Context) {
if err != nil { port, err := frp.StartFRPProxyFromRandom()
return err if err != nil {
c.String(http.StatusInternalServerError, fmt.Sprintf("error: %s", err))
}
c.String(http.StatusOK, strconv.Itoa(port))
})
// If there is a proxy port specified
// then starts the FRP server
//if config.FRPServerPort != "0" {
// go frp.StartFRPProxyFromRandom()
//}
// TODO check if IPV6 or Proxy port is specified
// if not update current entry as proxy address
// with appropriate port on IP Table
if config.BehindNAT == "True" {
table, err := p2p.ReadIpTable()
if err != nil {
return err
}
var lowestLatency int64
// random large number
lowestLatency = 10000000
for i, _ := range table.IpAddress {
// Checks if the ping is the lowest and if the following node is acting as a proxy
//if table.IpAddress[i].Latency.Milliseconds() < lowestLatency && table.IpAddress[i].ProxyPort != "" {
if table.IpAddress[i].Latency.Milliseconds() < lowestLatency {
lowestLatency = table.IpAddress[i].Latency.Milliseconds()
lowestLatencyIpAddress = table.IpAddress[i]
}
}
// If there is an identified node
if lowestLatency != 10000000 {
serverPort, err := frp.GetFRPServerPort("http://" + lowestLatencyIpAddress.Ipv4 + ":" + lowestLatencyIpAddress.ServerPort)
if err != nil {
return err
}
// Create 3 second delay to allow FRP server to start
time.Sleep(1 * time.Second)
// Starts FRP as a client with
proxyPort, err := frp.StartFRPClientForServer(lowestLatencyIpAddress.Ipv4, serverPort, config.ServerPort)
if err != nil {
return err
}
// updating with the current proxy address
ProxyIpAddr.Ipv4 = lowestLatencyIpAddress.Ipv4
ProxyIpAddr.ServerPort = proxyPort
ProxyIpAddr.Name = config.MachineName
ProxyIpAddr.NAT = "False"
ProxyIpAddr.EscapeImplementation = "FRP"
// append the following to the ip table
table.IpAddress = append(table.IpAddress, ProxyIpAddr)
// write information back to the IP Table
table.WriteIpTable()
// update ip table
go clientIPTable.UpdateIpTableListClient()
}
} }
// Run gin server on the specified port // Run gin server on the specified port

32
style.css Normal file
View File

@@ -0,0 +1,32 @@
body {
font-family: sans-serif;
}
span#discordJoin {
color: red;
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
/* General Page Changing */
body {
background: #121212; /* Background Color */
color: #FFFFFF; /* Text Color */
}
a:link{ /* Unvisited Link */
color: #03DAC5;
}
a:visited { /* Visited Link */
color: #BB86FC;
}
a:hover { /* Mouse over Link */
color: #018786;
}
span#discordJoin { /* Text Color Change */
color: #cc0227;
}
}