mirror of
https://github.com/valmojr/armatak.git
synced 2026-06-13 19:43:29 +00:00
Compare commits
99 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 753dcab26e | |||
| 2f53488ba8 | |||
| 323339e679 | |||
| 3f14a75e81 | |||
| 469a54c141 | |||
| 2ee9030c00 | |||
| 5b29a40990 | |||
| 708fe5e670 | |||
| e32aadda4e | |||
| c35b7f0268 | |||
| 876cf900c3 | |||
| 778ac0ac54 | |||
| b816144fb0 | |||
| 61ba9f6d63 | |||
| f88c02a7aa | |||
| 5ffc08e6f1 | |||
| 9392380c78 | |||
| a18343b81d | |||
|
|
13cd08c655 | ||
|
|
8fe14dc18d | ||
|
|
1bec26df8a | ||
|
|
c5d5da636f | ||
|
|
c2e137e67c | ||
|
|
de5ac9dbb5 | ||
|
|
ef3be1e768 | ||
|
|
9bda92d389 | ||
|
|
9763cb6697 | ||
|
|
5ac49e12f8 | ||
|
|
2108d20b01 | ||
|
|
524e7a0b3e | ||
|
|
7e4379ada4 | ||
|
|
572b2a360f | ||
|
|
083ccd2906 | ||
|
|
35a45d2cd4 | ||
|
|
2b241fbeaf | ||
|
|
ad9ba834cc | ||
|
|
469403d9b5 | ||
|
|
01ea754f57 | ||
|
|
fd8a25790e | ||
|
|
9ede7237b8 | ||
|
|
1242b1f79f | ||
|
|
9f8f326446 | ||
|
|
bf3b0cf0d4 | ||
|
|
42098401f2 | ||
|
|
cad4aaa1a5 | ||
|
|
ef787a6a09 | ||
|
|
2e017f97c9 | ||
|
|
fbd58d9426 | ||
|
|
894a11f087 | ||
|
|
dacb38fe45 | ||
|
|
2298254e24 | ||
|
|
853000a5c9 | ||
|
|
d0b47dd315 | ||
|
|
3c9dd1bea4 | ||
|
|
4d89ea7bc5 | ||
|
|
b97d13121e | ||
|
|
dcfdb0451c | ||
|
|
83b9082e87 | ||
|
|
2ab83a17b9 | ||
|
|
4ae35335e2 | ||
|
|
a1bf9472ae | ||
|
|
15129bb344 | ||
|
|
f143d80c34 | ||
|
|
e713c2f35f | ||
|
|
b1fac90e78 | ||
|
|
8341288457 | ||
|
|
4ad2b2d6dd | ||
|
|
485e67120c | ||
|
|
60f04bc4e8 | ||
|
|
35742847a7 | ||
|
|
c8c2b639ea | ||
|
|
0453470f1f | ||
|
|
d9da877da6 | ||
|
|
ed2b09a5f6 | ||
|
|
c1198ef287 | ||
|
|
58f6d3f349 | ||
|
|
67a7fa99af | ||
|
|
220c56f01d | ||
|
|
30be943581 | ||
|
|
a859e55c1b | ||
|
|
f491b06664 | ||
|
|
874686c975 | ||
|
|
2a7c1b8ae8 | ||
|
|
8ddbefee18 | ||
|
|
2b190d72c5 | ||
|
|
9fb8311aca | ||
|
|
d4f6ddb0fa | ||
|
|
0dd12a275b | ||
|
|
c45708066e | ||
|
|
0de4cf75e8 | ||
|
|
9bb4483266 | ||
|
|
ffc75cf4c4 | ||
|
|
2919805844 | ||
|
|
f3bff2b9cf | ||
|
|
74cda1c9a6 | ||
|
|
6c667d69b8 | ||
|
|
5f62304965 | ||
|
|
082831951e | ||
|
|
645a16394b |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,3 +1,5 @@
|
|||||||
|
*.rs linguist-language=Rust
|
||||||
|
|
||||||
*.paa filter=lfs diff=lfs merge=lfs -text
|
*.paa filter=lfs diff=lfs merge=lfs -text
|
||||||
*.p3d filter=lfs diff=lfs merge=lfs -text
|
*.p3d filter=lfs diff=lfs merge=lfs -text
|
||||||
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
*.jpeg filter=lfs diff=lfs merge=lfs -text
|
||||||
|
|||||||
33
.github/workflows/pack_early.yaml
vendored
33
.github/workflows/pack_early.yaml
vendored
@@ -5,32 +5,6 @@ on:
|
|||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
package_application:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
lfs: true
|
|
||||||
- name: set up JDK 11
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '17'
|
|
||||||
distribution: 'zulu'
|
|
||||||
cache: gradle
|
|
||||||
|
|
||||||
- name: Grant execute permission for gradlew
|
|
||||||
run: chmod +x gradlew
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: ./gradlew assembleDebug
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: simtak
|
|
||||||
path: app/build/outputs/apk/debug/app-debug.apk
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
build_extension:
|
build_extension:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -66,7 +40,7 @@ jobs:
|
|||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
package:
|
package:
|
||||||
needs: [build_extension, package_application]
|
needs: [build_extension]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
@@ -88,11 +62,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: x86_64-unknown-linux-gnu
|
name: x86_64-unknown-linux-gnu
|
||||||
- run: mv ./libarmatak.so ./armatak_x64.so
|
- run: mv ./libarmatak.so ./armatak_x64.so
|
||||||
- name: Download Android Application Installer
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: simtak
|
|
||||||
- run: mv ./app-debug.apk ./simtak.apk
|
|
||||||
- name: Setup HEMTT
|
- name: Setup HEMTT
|
||||||
uses: arma-actions/hemtt@v1
|
uses: arma-actions/hemtt@v1
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
33
.github/workflows/publish.yaml
vendored
33
.github/workflows/publish.yaml
vendored
@@ -5,32 +5,6 @@ on:
|
|||||||
branches: [ main ]
|
branches: [ main ]
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
package_application:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
lfs: true
|
|
||||||
- name: set up JDK 11
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '17'
|
|
||||||
distribution: 'zulu'
|
|
||||||
cache: gradle
|
|
||||||
|
|
||||||
- name: Grant execute permission for gradlew
|
|
||||||
run: chmod +x gradlew
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: ./gradlew assembleDebug
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: simtak
|
|
||||||
path: app/build/outputs/apk/debug/app-debug.apk
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
build_extension:
|
build_extension:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -66,7 +40,7 @@ jobs:
|
|||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
package:
|
package:
|
||||||
needs: [build_extension, package_application]
|
needs: [build_extension]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
@@ -88,11 +62,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: x86_64-unknown-linux-gnu
|
name: x86_64-unknown-linux-gnu
|
||||||
- run: mv ./libarmatak.so ./armatak_x64.so
|
- run: mv ./libarmatak.so ./armatak_x64.so
|
||||||
- name: Download Android Application Installer
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: simtak
|
|
||||||
- run: mv ./app-debug.apk ./simtak.apk
|
|
||||||
- name: Setup HEMTT
|
- name: Setup HEMTT
|
||||||
uses: arma-actions/hemtt@v1
|
uses: arma-actions/hemtt@v1
|
||||||
- name: Build
|
- name: Build
|
||||||
|
|||||||
34
.github/workflows/release_drafter.yaml
vendored
34
.github/workflows/release_drafter.yaml
vendored
@@ -9,31 +9,6 @@ permissions:
|
|||||||
contents: write
|
contents: write
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
package_application:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- name: Checkout Repo
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
lfs: true
|
|
||||||
- name: Set up JDK 11
|
|
||||||
uses: actions/setup-java@v4
|
|
||||||
with:
|
|
||||||
java-version: '17'
|
|
||||||
distribution: 'zulu'
|
|
||||||
cache: gradle
|
|
||||||
- name: Grant execute permission for gradlew
|
|
||||||
run: chmod +x gradlew
|
|
||||||
- name: Build with Gradle
|
|
||||||
run: ./gradlew assembleDebug
|
|
||||||
- name: Upload Artifact
|
|
||||||
uses: actions/upload-artifact@v4
|
|
||||||
with:
|
|
||||||
name: simtak
|
|
||||||
path: app/build/outputs/apk/debug/app-debug.apk
|
|
||||||
if-no-files-found: error
|
|
||||||
retention-days: 1
|
|
||||||
|
|
||||||
build_extension:
|
build_extension:
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
@@ -69,7 +44,7 @@ jobs:
|
|||||||
retention-days: 1
|
retention-days: 1
|
||||||
|
|
||||||
package:
|
package:
|
||||||
needs: [build_extension, package_application]
|
needs: [build_extension]
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Repo
|
- name: Checkout Repo
|
||||||
@@ -91,11 +66,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
name: x86_64-unknown-linux-gnu
|
name: x86_64-unknown-linux-gnu
|
||||||
- run: mv ./libarmatak.so ./armatak_x64.so
|
- run: mv ./libarmatak.so ./armatak_x64.so
|
||||||
- name: Download Android Application Installer
|
|
||||||
uses: actions/download-artifact@v4
|
|
||||||
with:
|
|
||||||
name: simtak
|
|
||||||
- run: mv ./app-debug.apk ./simtak.apk
|
|
||||||
- name: Setup HEMTT
|
- name: Setup HEMTT
|
||||||
uses: arma-actions/hemtt@v1
|
uses: arma-actions/hemtt@v1
|
||||||
- name: Build
|
- name: Build
|
||||||
@@ -121,7 +91,7 @@ jobs:
|
|||||||
release_name: ${{ github.ref }}
|
release_name: ${{ github.ref }}
|
||||||
body: |
|
body: |
|
||||||
Changes in this release:
|
Changes in this release:
|
||||||
${{ env.COMMIT_MESSAGES }}
|
${{ github.event.head_commit.message }}
|
||||||
draft: true
|
draft: true
|
||||||
prerelease: false
|
prerelease: false
|
||||||
- name: Upload Release Asset
|
- name: Upload Release Asset
|
||||||
|
|||||||
79
.github/workflows/release_publisher.yaml
vendored
Normal file
79
.github/workflows/release_publisher.yaml
vendored
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
name: Publish Production
|
||||||
|
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build_extension:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os_target:
|
||||||
|
- { os: "windows-latest", target: "i686-pc-windows-msvc", artifact: "armatak.dll", name: "armatak.dll" }
|
||||||
|
- { os: "windows-latest", target: "x86_64-pc-windows-msvc", artifact: "armatak.dll", name: "armatak_x64.dll" }
|
||||||
|
- { os: "ubuntu-latest", target: "x86_64-unknown-linux-gnu", artifact: "libarmatak.so", name: "armatak.so" }
|
||||||
|
runs-on: ${{ matrix.os_target.os }}
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
- name: Install Rust Toolchain
|
||||||
|
uses: actions-rs/toolchain@v1
|
||||||
|
with:
|
||||||
|
target: ${{ matrix.os_target.target }}
|
||||||
|
toolchain: stable
|
||||||
|
default: true
|
||||||
|
- name: Install Dependencies (Linux only)
|
||||||
|
if: matrix.os_target.os == 'ubuntu-latest'
|
||||||
|
run: sudo apt-get update && sudo apt-get install -y build-essential
|
||||||
|
- name: Cargo Build
|
||||||
|
run: cargo build --release --target ${{ matrix.os_target.target }}
|
||||||
|
- name: check stuff
|
||||||
|
run: ls target/release
|
||||||
|
- name: Upload Artifact
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: ${{ matrix.os_target.target }}
|
||||||
|
path: target/${{ matrix.os_target.target }}/release/${{ matrix.os_target.artifact }}
|
||||||
|
if-no-files-found: error
|
||||||
|
retention-days: 1
|
||||||
|
|
||||||
|
package:
|
||||||
|
needs: [build_extension]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout Repo
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
lfs: true
|
||||||
|
- run: mkdir -p ./target/release
|
||||||
|
- name: Download Windows x64 Artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: x86_64-pc-windows-msvc
|
||||||
|
- run: mv ./armatak.dll ./armatak_x64.dll
|
||||||
|
- name: Download Windows x86 Artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: i686-pc-windows-msvc
|
||||||
|
- name: Download Linux x64 Artifact
|
||||||
|
uses: actions/download-artifact@v4
|
||||||
|
with:
|
||||||
|
name: x86_64-unknown-linux-gnu
|
||||||
|
- run: mv ./libarmatak.so ./armatak_x64.so
|
||||||
|
- name: Setup HEMTT
|
||||||
|
uses: arma-actions/hemtt@v1
|
||||||
|
- name: Build
|
||||||
|
run: hemtt release
|
||||||
|
- name: Extract Zipped Mod
|
||||||
|
run: unzip releases/armatak-latest.zip -d releases
|
||||||
|
- uses: arma-actions/workshop-upload@v1
|
||||||
|
with:
|
||||||
|
appId: '107410'
|
||||||
|
itemId: ${{ secrets.STEAM_WORKSHOP_PROD_ID }}
|
||||||
|
contentPath: releases/@armatak
|
||||||
|
changelog: 'Update'
|
||||||
|
env:
|
||||||
|
STEAM_USERNAME: ${{ secrets.STEAM_USERNAME }}
|
||||||
|
STEAM_PASSWORD: ${{ secrets.STEAM_PASSWORD }}
|
||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,6 +3,7 @@
|
|||||||
hemtt
|
hemtt
|
||||||
hemtt.exe
|
hemtt.exe
|
||||||
*.biprivatekey
|
*.biprivatekey
|
||||||
|
.hemttprivatekey
|
||||||
source/
|
source/
|
||||||
.vscode
|
.vscode
|
||||||
releases/
|
releases/
|
||||||
|
|||||||
@@ -25,8 +25,7 @@ include = [
|
|||||||
"LICENSE",
|
"LICENSE",
|
||||||
"*.dll",
|
"*.dll",
|
||||||
"*.so",
|
"*.so",
|
||||||
"*.paa",
|
"*.paa"
|
||||||
"simtak.apk"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[properties]
|
[properties]
|
||||||
@@ -38,30 +37,31 @@ preset = "Hemtt"
|
|||||||
|
|
||||||
[hemtt.launch.default]
|
[hemtt.launch.default]
|
||||||
workshop = [
|
workshop = [
|
||||||
"450814997", # CBA
|
"450814997", # CBA_A3
|
||||||
"463939057", # ACE
|
"463939057", # ACE
|
||||||
"623475643", # 3den enhanced
|
|
||||||
"1779063631", # Zeus enhanced
|
|
||||||
"1673595418", # User Input Menus
|
|
||||||
"1678581937", # Extended Function Viewer
|
|
||||||
"1231625987", #Debug Console
|
|
||||||
"751965892", # ACRE2
|
"751965892", # ACRE2
|
||||||
|
"2522638637", # ACE Extended Arsenal
|
||||||
|
"333310405", # Enhanced Movement
|
||||||
|
"2034363662", # Enhanced Movement Rework
|
||||||
|
"2941986336", # Hatchet Interaction Framework - Stable Version
|
||||||
|
"1745501605", # Hatchet H-60 pack - Stable Version
|
||||||
"843577117", # RHSUSAF
|
"843577117", # RHSUSAF
|
||||||
"3030830594", # Western Dusk
|
"843425103", # RHSAFRF
|
||||||
|
"843632231", # RHSSAF
|
||||||
|
"843593391", # RHSGREF
|
||||||
|
"1673456286", # 3CB Factions
|
||||||
|
"623475643", # 3den Enhanced
|
||||||
|
"2257686620", # Blastcore Murr Edition
|
||||||
|
"583496184", # CUP Terrains - Core
|
||||||
|
"3078351739", # Kunduz River
|
||||||
|
"1858075458", # LAMBS_Danger.fsm
|
||||||
|
"1808238502", # LAMBS_Suppression
|
||||||
|
"3425368881", # M4A1_URGI
|
||||||
"2268351256", # Tier One Weapons
|
"2268351256", # Tier One Weapons
|
||||||
"583496184", # CUP Terrains
|
"2560276469", # Restrict Markers
|
||||||
"583544987", # CUP Maps
|
"3493557838" # Ballad of the Green Berets
|
||||||
"3015795970", # No zoom
|
|
||||||
"2941986336", # Hatchet Framework
|
|
||||||
"1745501605", # Hatchet H-60 Pack
|
|
||||||
"333310405", # Enhanced Moviments
|
|
||||||
"2034363662", # Enhanced Moviments Rework
|
|
||||||
"2257686620", # Blastcore Murr
|
|
||||||
"3407948300", # JSRS Sound Mod
|
|
||||||
]
|
]
|
||||||
|
|
||||||
mission = "armatak_jtac.Mountains_ACR"
|
|
||||||
|
|
||||||
parameters = [
|
parameters = [
|
||||||
"-skipIntro",
|
"-skipIntro",
|
||||||
"-noSplash",
|
"-noSplash",
|
||||||
|
|||||||
1895
Cargo.lock
generated
1895
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
15
Cargo.toml
15
Cargo.toml
@@ -6,21 +6,14 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
arma-rs = "1.10.4"
|
arma-rs = "1.10.4"
|
||||||
chrono = "0.4.39"
|
chrono = "0.4.39"
|
||||||
futures = "0.3.31"
|
|
||||||
futures-util = "0.3.31"
|
|
||||||
http = "1.1.0"
|
|
||||||
lazy_static = "1.5.0"
|
lazy_static = "1.5.0"
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
log4rs = "1.3.0"
|
log4rs = "1.3.0"
|
||||||
once_cell = "1.19.0"
|
reqwest = { version = "0.12.15", default-features = false, features = ["blocking", "json", "rustls-tls"] }
|
||||||
qrcode = "0.14.1"
|
rcgen = { version = "0.13.2", default-features = false, features = ["crypto", "pem", "aws_lc_rs"] }
|
||||||
regex = "1.10.6"
|
rustls = "0.23.23"
|
||||||
reqwest = { version = "0.12.7", features = ["blocking"] }
|
rustls-pemfile = "2.2.0"
|
||||||
serde = { version = "1.0.210", features = ["derive"] }
|
serde = { version = "1.0.210", features = ["derive"] }
|
||||||
serde_json = "1.0.128"
|
|
||||||
tokio = { version = "1.40", features = ["full"] }
|
|
||||||
tokio-tungstenite = "0.24.0"
|
|
||||||
ws = "0.9.2"
|
|
||||||
|
|
||||||
[dependencies.uuid]
|
[dependencies.uuid]
|
||||||
version = "1.10.0"
|
version = "1.10.0"
|
||||||
|
|||||||
@@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
ARMATAK is a server side Arma 3 addons for streaming unit positions to TAK Clients in sessions on real locations maps. It can be runned both as a clientside mod or a serverside mod, when runned serverside, it will create a TCP Socket connection between Arma 3 and the TAK Server, sending the game session information into it. When used clientside, Arma 3 will host a websocket server that you can connect to your phone and mock the phone's location to the player's in game location.
|
ARMATAK is a server side Arma 3 addons for streaming unit positions to TAK Clients in sessions on real locations maps. It can be runned both as a clientside mod or a serverside mod, when runned serverside, it will create a TCP Socket connection between Arma 3 and the TAK Server, sending the game session information into it. When used clientside, Arma 3 will host a websocket server that you can connect to your phone and mock the phone's location to the player's in game location.
|
||||||
|
|
||||||
|
The server-side CoT router supports two transports:
|
||||||
|
- Plain TCP, for legacy TAK ingress.
|
||||||
|
- Mutual TLS, using the TAK Server authentication API, so the Arma session can publish as an authenticated TAK device on port `8089`.
|
||||||
|
|
||||||
## Get in Touch
|
## Get in Touch
|
||||||
|
|
||||||
[Join the Discord Server for ARMATAK!](https://discord.gg/svK64PCycU)
|
[Join the Discord Server for ARMATAK!](https://discord.gg/svK64PCycU)
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
PREP(convertClientLocation);
|
PREP(convertClientLocation);
|
||||||
PREP(extractClientPosition);
|
PREP(extractClientPosition);
|
||||||
|
PREP(startUDPSocket);
|
||||||
|
|||||||
@@ -4,11 +4,5 @@ if (!hasInterface) exitWith {};
|
|||||||
|
|
||||||
_local_address = "armatak" callExtension ["local_ip", []] select 0;
|
_local_address = "armatak" callExtension ["local_ip", []] select 0;
|
||||||
|
|
||||||
"armatak" callExtension ["websocket:start", []];
|
|
||||||
|
|
||||||
SETVAR(player,GVAR(localAddress),_local_address);
|
SETVAR(player,GVAR(localAddress),_local_address);
|
||||||
SETVAR(player,GVAR(eudConnected),false);
|
SETVAR(player,GVAR(eudConnected),false);
|
||||||
|
|
||||||
[{
|
|
||||||
"armatak" callExtension ["websocket:location", [player call armatak_client_fnc_extractClientPosition]];
|
|
||||||
}, 1, []] call CBA_fnc_addPerFrameHandler;
|
|
||||||
|
|||||||
@@ -16,4 +16,20 @@ class CfgPatches {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CfgVehicles {
|
||||||
|
class Man;
|
||||||
|
class CAManBase: Man {
|
||||||
|
class ACE_SelfActions {
|
||||||
|
class danceParty {
|
||||||
|
displayName = "Connect to EUD";
|
||||||
|
condition = "!(player getVariable ['armatak_client_eudConnected', false])";
|
||||||
|
exceptions[] = {};
|
||||||
|
statement = "createDialog 'armatak_udp_socket_start_dialog'";
|
||||||
|
icon = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
#include "CfgEventHandlers.hpp"
|
#include "CfgEventHandlers.hpp"
|
||||||
|
#include "dialog.hpp"
|
||||||
|
|||||||
73
addons/client/dialog.hpp
Normal file
73
addons/client/dialog.hpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
class RscText;
|
||||||
|
class RscBackground;
|
||||||
|
class RscButton;
|
||||||
|
class RscEdit;
|
||||||
|
|
||||||
|
class armatak_udp_socket_start_dialog {
|
||||||
|
idd = 999091;
|
||||||
|
movingEnable = 0;
|
||||||
|
class ControlsBackground {
|
||||||
|
class armatak_gui_module_udp_socket_dialog_main_frame: RscBackground {
|
||||||
|
idc = 16960;
|
||||||
|
x = "0.386562 * safezoneW + safezoneX";
|
||||||
|
y = "0.401 * safezoneH + safezoneY";
|
||||||
|
w = "0.216563 * safezoneW";
|
||||||
|
h = "0.242 * safezoneH";
|
||||||
|
colorBackground[]={0,0,0,0.45};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class Controls {
|
||||||
|
class armatak_gui_module_udp_socket_dialog_address_edit: RscEdit {
|
||||||
|
idc = 16961;
|
||||||
|
text = "168.15.0.3";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.445 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[]={0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class armatak_gui_module_udp_socket_dialog_address_port_edit: RscEdit {
|
||||||
|
idc = 16962;
|
||||||
|
text = "4349";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.522 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[]={0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class armatak_gui_module_udp_socket_dialog_address_text: RscText {
|
||||||
|
idc = 16963;
|
||||||
|
text = "Phone's Socket Local Address";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.412 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.033 * safezoneH";
|
||||||
|
};
|
||||||
|
class armatak_gui_module_udp_socket_dialog_address_port_text: RscText {
|
||||||
|
idc = 16964;
|
||||||
|
text = "Phone's Socket Local Port";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.489 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.033 * safezoneH";
|
||||||
|
};
|
||||||
|
class armatak_gui_module_udp_socket_dialog_address_button_cancel: RscButton {
|
||||||
|
idc = 16965;
|
||||||
|
text = "Cancel";
|
||||||
|
action = "closeDialog 2;";
|
||||||
|
x = "0.551563 * safezoneW + safezoneX";
|
||||||
|
y = "0.577 * safezoneH + safezoneY";
|
||||||
|
w = "0.0464063 * safezoneW";
|
||||||
|
h = "0.055 * safezoneH";
|
||||||
|
};
|
||||||
|
class armatak_gui_module_udp_socket_dialog_address_button_ok: RscButton {
|
||||||
|
idc = 16966;
|
||||||
|
text = "Ok";
|
||||||
|
action = QUOTE(call FUNC(startUDPSocket));
|
||||||
|
x = "0.5 * safezoneW + safezoneX";
|
||||||
|
y = "0.577 * safezoneH + safezoneY";
|
||||||
|
w = "0.0464063 * safezoneW";
|
||||||
|
h = "0.055 * safezoneH";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
* [player] call armatak_client_fnc_convertClientLocation;
|
* [player] call armatak_client_fnc_convertClientLocation;
|
||||||
*
|
*
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
params["_latitude", "_longitude", "_altitude"];
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
@@ -38,6 +38,9 @@ switch (toLower worldName) do {
|
|||||||
case "vr": {
|
case "vr": {
|
||||||
_realLocation = _position call armatak_fnc_convert_to_vr;
|
_realLocation = _position call armatak_fnc_convert_to_vr;
|
||||||
};
|
};
|
||||||
|
case "lawn": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_lawn;
|
||||||
|
};
|
||||||
case "cucui": {
|
case "cucui": {
|
||||||
_realLocation = _position call armatak_fnc_convert_to_cucui;
|
_realLocation = _position call armatak_fnc_convert_to_cucui;
|
||||||
};
|
};
|
||||||
@@ -71,6 +74,45 @@ switch (toLower worldName) do {
|
|||||||
case "kunduz": {
|
case "kunduz": {
|
||||||
_realLocation = _position call armatak_fnc_convert_to_kunduz;
|
_realLocation = _position call armatak_fnc_convert_to_kunduz;
|
||||||
};
|
};
|
||||||
|
case "kunduz_valley": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_kunduz_valley;
|
||||||
|
};
|
||||||
|
case "malvinasfalkands": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_malvinas_malvinasfalkands;
|
||||||
|
};
|
||||||
|
case "pebble_island_airfield": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_malvinas_pebble_island_airfield;
|
||||||
|
};
|
||||||
|
case "p_argentino_stanley": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_malvinas_p_argentino_stanley;
|
||||||
|
};
|
||||||
|
case "top_malo_house": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_malvinas_top_malo_house;
|
||||||
|
};
|
||||||
|
case "pradera_ganso": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_malvinas_pradera_ganso;
|
||||||
|
};
|
||||||
|
case "tanoa": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_tanoa;
|
||||||
|
};
|
||||||
|
case "zagor_zagorsk_reserved_forest": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_zagor_zagorsk_reserved_forest;
|
||||||
|
};
|
||||||
|
case "umb_colombia": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_colombia;
|
||||||
|
};
|
||||||
|
case "clafghan": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_clafghan;
|
||||||
|
};
|
||||||
|
case "rut_mandol": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_rut_mandol;
|
||||||
|
};
|
||||||
|
case "hellanmaa": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_hellanmaa;
|
||||||
|
};
|
||||||
|
case "hellanmaaw": {
|
||||||
|
_realLocation = _position call armatak_fnc_convert_to_hellanmaa;
|
||||||
|
};
|
||||||
default {
|
default {
|
||||||
_warning = format ["<t color='#FF8021'>ARMATAK</t><br/> %1", "Unsupported Map"];
|
_warning = format ["<t color='#FF8021'>ARMATAK</t><br/> %1", "Unsupported Map"];
|
||||||
[[_warning, 1.5]] call CBA_fnc_notify;
|
[[_warning, 1.5]] call CBA_fnc_notify;
|
||||||
|
|||||||
@@ -18,13 +18,12 @@
|
|||||||
|
|
||||||
params["_unit"];
|
params["_unit"];
|
||||||
|
|
||||||
private _location = (getPos _unit) call FUNC(convertClientLocation);
|
private _uuid = _unit call armatak_fnc_extract_uuid;
|
||||||
|
private _pos = (getPos _unit) call FUNC(convertClientLocation);
|
||||||
|
private _callsign = _unit call armatak_fnc_extract_unit_callsign;
|
||||||
|
private _bearing = parseNumber ((getDir _unit) toFixed 0);
|
||||||
|
private _speed = speed _unit / 3.6;
|
||||||
|
|
||||||
private _atak_latitude = _location select 0;
|
_payload = [_uuid, _pos select 0, _pos select 1, _pos select 2, _callsign, _bearing, _speed, _callsign];
|
||||||
private _atak_longitude = _location select 1;
|
|
||||||
private _atak_altitude = _location select 2;
|
|
||||||
private _atak_bearing = parseNumber ((getDir _unit) toFixed 0);
|
|
||||||
|
|
||||||
_unit_info = [_atak_latitude,_atak_longitude,_atak_altitude,_atak_bearing];
|
_payload
|
||||||
|
|
||||||
_unit_info
|
|
||||||
|
|||||||
31
addons/client/functions/fnc_startUDPSocket.sqf
Normal file
31
addons/client/functions/fnc_startUDPSocket.sqf
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
params ["_logic"];
|
||||||
|
|
||||||
|
_socket_is_running = player getVariable [QGVAR(eudConnected), false];
|
||||||
|
|
||||||
|
if (_socket_is_running) exitWith {
|
||||||
|
["Socket is already running", "error", "UDP Socket"] call EFUNC(main,notify);
|
||||||
|
closeDialog 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
disableSerialization;
|
||||||
|
|
||||||
|
_udp_socket_instance_address = ctrlText 16961;
|
||||||
|
_udp_socket_instance_port = ctrlText 16962;
|
||||||
|
|
||||||
|
_udp_socket_fulladdress = ((_udp_socket_instance_address) + ":" + (_udp_socket_instance_port));
|
||||||
|
|
||||||
|
player setVariable [QGVAR(udp_socket_address), _udp_socket_fulladdress];
|
||||||
|
player setVariable [QGVAR(eudConnected), true];
|
||||||
|
|
||||||
|
"armatak" callExtension ["udp_socket:start", [_udp_socket_fulladdress]];
|
||||||
|
|
||||||
|
[{
|
||||||
|
if (player getVariable [QGVAR(eudConnected), false]) then {
|
||||||
|
"armatak" callExtension ["udp_socket:send_gps_cot", [player call FUNC(extractClientPosition)]];
|
||||||
|
};
|
||||||
|
}, 0.5, []] call CBA_fnc_addPerFrameHandler;
|
||||||
|
|
||||||
|
deleteVehicle _logic;
|
||||||
|
closeDialog 1;
|
||||||
@@ -78,6 +78,16 @@ class Cfg3den {
|
|||||||
condition = "objectVehicle";
|
condition = "objectVehicle";
|
||||||
typeName = "STRING";
|
typeName = "STRING";
|
||||||
};
|
};
|
||||||
|
class armatak_attribute_marker_video_url {
|
||||||
|
displayName = "Video Feed URL";
|
||||||
|
tooltip = "Video feed URL injected into __video on TAK";
|
||||||
|
property = "armatak_attribute_marker_video_url";
|
||||||
|
control = "Edit";
|
||||||
|
expression = "_this setVariable ['armatak_attribute_marker_video_url',_value]";
|
||||||
|
defaultValue = "''";
|
||||||
|
condition = "objectVehicle";
|
||||||
|
typeName = "STRING";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,6 +10,9 @@ class CfgFunctions {
|
|||||||
class send_group_cots {
|
class send_group_cots {
|
||||||
file = "\armatak\armatak\addons\main\functions\api\fn_send_group_cots.sqf";
|
file = "\armatak\armatak\addons\main\functions\api\fn_send_group_cots.sqf";
|
||||||
};
|
};
|
||||||
|
class send_enemy_cot {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\api\fn_send_enemy_cot.sqf";
|
||||||
|
};
|
||||||
class send_eud_cot {
|
class send_eud_cot {
|
||||||
file = "\armatak\armatak\addons\main\functions\api\fn_send_eud_cot.sqf";
|
file = "\armatak\armatak\addons\main\functions\api\fn_send_eud_cot.sqf";
|
||||||
};
|
};
|
||||||
@@ -28,9 +31,15 @@ class CfgFunctions {
|
|||||||
class extract_marker_callsign {
|
class extract_marker_callsign {
|
||||||
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_marker_callsign.sqf";
|
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_marker_callsign.sqf";
|
||||||
};
|
};
|
||||||
|
class extract_marker_video_url {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_marker_video_url.sqf";
|
||||||
|
};
|
||||||
class extract_role {
|
class extract_role {
|
||||||
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_role.sqf";
|
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_role.sqf";
|
||||||
};
|
};
|
||||||
|
class extract_sensor_data {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_sensor_data.sqf";
|
||||||
|
};
|
||||||
class extract_unit_callsign {
|
class extract_unit_callsign {
|
||||||
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_unit_callsign.sqf";
|
file = "\armatak\armatak\addons\main\functions\extract_data\fn_extract_unit_callsign.sqf";
|
||||||
};
|
};
|
||||||
@@ -59,12 +68,33 @@ class CfgFunctions {
|
|||||||
class convert_to_kunduz {
|
class convert_to_kunduz {
|
||||||
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_kunduz.sqf";
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_kunduz.sqf";
|
||||||
};
|
};
|
||||||
|
class convert_to_kunduz_valley {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_kunduz_valley.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_lawn {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_lawn.sqf";
|
||||||
|
};
|
||||||
class convert_to_livonia {
|
class convert_to_livonia {
|
||||||
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_livonia.sqf";
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_livonia.sqf";
|
||||||
};
|
};
|
||||||
class convert_to_malden {
|
class convert_to_malden {
|
||||||
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malden.sqf";
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malden.sqf";
|
||||||
};
|
};
|
||||||
|
class convert_to_malvinas_malvinasfalkands {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malvinas_malvinasfalkands.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_malvinas_p_argentino_stanley {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malvinas_p_argentino_stanley.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_malvinas_pebble_island_airfield {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malvinas_pebble_island_airfield.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_malvinas_pradera_ganso {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malvinas_pradera_ganso.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_malvinas_top_malo_house {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_malvinas_top_malo_house.sqf";
|
||||||
|
};
|
||||||
class convert_to_southen_sahrani {
|
class convert_to_southen_sahrani {
|
||||||
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_southen_sahrani.sqf";
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_southen_sahrani.sqf";
|
||||||
};
|
};
|
||||||
@@ -83,6 +113,21 @@ class CfgFunctions {
|
|||||||
class convert_to_vr {
|
class convert_to_vr {
|
||||||
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_vr.sqf";
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_vr.sqf";
|
||||||
};
|
};
|
||||||
|
class convert_to_zagor_zagorsk_reserved_forest {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_zagor_zagorsk_reserved_forest.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_colombia {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_colombia.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_clafghan {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_clafghan.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_rut_mandol {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_rut_mandol.sqf";
|
||||||
|
};
|
||||||
|
class convert_to_hellanmaa {
|
||||||
|
file = "\armatak\armatak\addons\main\functions\map\fn_convert_to_hellanmaa.sqf";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@@ -3,41 +3,59 @@
|
|||||||
addMissionEventHandler ["ExtensionCallback", {
|
addMissionEventHandler ["ExtensionCallback", {
|
||||||
params ["_name", "_function", "_data"];
|
params ["_name", "_function", "_data"];
|
||||||
|
|
||||||
if (_name == "WEBSOCKET") then {
|
switch (_name) do {
|
||||||
|
case "UDP SOCKET": {
|
||||||
[_function, "success", _name] call FUNC(notify);
|
[_function, "success", _name] call FUNC(notify);
|
||||||
|
|
||||||
switch (_function) do {
|
switch (_function) do {
|
||||||
case "EUD connected": {
|
case "EUD Connected": {
|
||||||
SETVAR(player,EGVAR(client,eudConnected),true);
|
SETVAR(player,EGVAR(client,eudConnected),true);
|
||||||
};
|
};
|
||||||
case "EUD disconnected": {
|
case "EUD Disconnected": {
|
||||||
SETVAR(player,GVAR(eudConnected),false);
|
SETVAR(player,EGVAR(client,eudConnected),false);
|
||||||
};
|
};
|
||||||
default {};
|
default {};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
case "UDP SOCKET WARNING": {
|
||||||
if (_name == "WEBSOCKET WARNING") then {
|
[_function, "warning", "UDP Socket"] call FUNC(notify);
|
||||||
[_function, "warning", "WEBSOCKET"] call FUNC(notify);
|
|
||||||
};
|
};
|
||||||
|
case "UDP SOCKET ERROR": {
|
||||||
if (_name == "WEBSOCKET ERROR") then {
|
|
||||||
[_function, "error", _name] call FUNC(notify);
|
[_function, "error", _name] call FUNC(notify);
|
||||||
|
|
||||||
|
if (_function == "UDP Socket is not running") then {
|
||||||
|
SETVAR(player,EGVAR(client,eudConnected),false);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_name == "TCP SOCKET") then {
|
if (_function == "failed to bind UDP socket") then {
|
||||||
|
SETVAR(player,EGVAR(client,eudConnected),false);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
case "TCP SOCKET": {
|
||||||
[_function, "success", _name] call FUNC(notify);
|
[_function, "success", _name] call FUNC(notify);
|
||||||
};
|
};
|
||||||
|
case "TCP SOCKET ERROR": {
|
||||||
if (_name == "TCP SOCKET ERROR") then {
|
_message = _function;
|
||||||
[_function, "error", _name] call FUNC(notify);
|
if (_data isNotEqualTo "") then {
|
||||||
|
_message = format ["%1: %2", _function, _data];
|
||||||
};
|
};
|
||||||
|
|
||||||
if (_name == "VIDEO") then {
|
[_message, "error", _name] call FUNC(notify);
|
||||||
|
};
|
||||||
|
case "VIDEO": {
|
||||||
[_function, "success", _name] call FUNC(notify);
|
[_function, "success", _name] call FUNC(notify);
|
||||||
};
|
};
|
||||||
|
case "VIDEO ERROR": {
|
||||||
if (_name == "VIDEO ERROR") then {
|
|
||||||
[_function, "error", _name] call FUNC(notify);
|
[_function, "error", _name] call FUNC(notify);
|
||||||
|
|
||||||
|
SETVAR(player,EGVAR(video,isStreaming),false);
|
||||||
|
};
|
||||||
|
default {
|
||||||
|
"armatak" callExtension ["log",["error", (_name + _function + _data)]];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}];
|
}];
|
||||||
|
|
||||||
|
GVAR(group_colors) = ["White", "Yellow", "Orange", "Magenta", "Red", "Maroon", "Purple", "DarkBlue", "Blue", "Cyan", "Teal", "Green", "DarkGreen", "Brown"];
|
||||||
|
|
||||||
|
missionNamespace setVariable [QGVAR(group_colors), GVAR(group_colors)];
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ params ["_unit"];
|
|||||||
_digitalPointer = laserTarget _unit;
|
_digitalPointer = laserTarget _unit;
|
||||||
|
|
||||||
if (!isNull _digitalPointer) then {
|
if (!isNull _digitalPointer) then {
|
||||||
_digitalPointerPosition = _digitalPointer call armatak_fnc_extract_position;
|
_digitalPointerPosition = _digitalPointer call armatak_client_fnc_extractClientPosition;
|
||||||
|
|
||||||
_link_uid = [_unit] call armatak_fnc_extract_uuid;
|
_link_uid = [_unit] call armatak_fnc_extract_uuid;
|
||||||
_contact_callsign = ([player] call armatak_fnc_extract_callsign) + ".DP1";
|
_contact_callsign = ([player] call armatak_fnc_extract_unit_callsign) + ".DP1";
|
||||||
|
|
||||||
_dpCot = [_link_uid, _contact_callsign, _digitalPointerPosition select 0, _digitalPointerPosition select 1, _digitalPointerPosition select 2];
|
_dpCot = [_link_uid, _contact_callsign, _digitalPointerPosition select 1, _digitalPointerPosition select 2, _digitalPointerPosition select 3];
|
||||||
|
|
||||||
"armatak" callExtension ["tcp_socket:send_digital_pointer_cot", [_dpCot]];
|
"armatak" callExtension ["tcp_socket:cot:digital_pointer", [_dpCot]];
|
||||||
};
|
};
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
// function name: armatak_fnc_extract_drone
|
// function name: armatak_fnc_send_drone_cot
|
||||||
// function author: Valmo
|
// function author: Valmo
|
||||||
// function description: Gets the drone information for the CoT Router
|
// function description: Gets the drone information for the CoT Router
|
||||||
|
|
||||||
params["_drone"];
|
params["_drone"];
|
||||||
|
|
||||||
private _atak_role = "a-f-A";
|
private _atak_role = "a-f-A";
|
||||||
private _atak_callsign = [_unit] call armatak_fnc_extract_callsign;
|
private _atak_callsign = [_drone] call armatak_fnc_extract_marker_callsign;
|
||||||
|
|
||||||
switch (side _drone) do {
|
switch (side _drone) do {
|
||||||
case "WEST": {
|
case "WEST": {
|
||||||
@@ -25,4 +25,10 @@ switch (side _drone) do {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_pre_defined_role = _drone getVariable "_atak_group_role";
|
||||||
|
|
||||||
|
if (!isNil "_pre_defined_role") then {
|
||||||
|
_callsign = _pre_defined_role;
|
||||||
|
};
|
||||||
|
|
||||||
_cot = [_drone, _atak_role, _atak_callsign] call armatak_fnc_send_marker_cot;
|
_cot = [_drone, _atak_role, _atak_callsign] call armatak_fnc_send_marker_cot;
|
||||||
15
addons/main/functions/api/fn_send_enemy_cot.sqf
Normal file
15
addons/main/functions/api/fn_send_enemy_cot.sqf
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
// function name: armatak_fnc_send_eud_cot
|
||||||
|
// function author: Valmo
|
||||||
|
// function description: Gets the information necessary for generating the EUD Cursor Over Time
|
||||||
|
|
||||||
|
params ["_unit"];
|
||||||
|
|
||||||
|
_unit_position = _unit call armatak_client_fnc_extractClientPosition;
|
||||||
|
|
||||||
|
_uuid = _unit call armatak_fnc_extract_uuid;
|
||||||
|
_type = _unit call armatak_fnc_extract_role;
|
||||||
|
_callsign = _unit call armatak_fnc_extract_marker_callsign;
|
||||||
|
|
||||||
|
_marker_cot = [_uuid, _type, _unit_position select 1, _unit_position select 2, _unit_position select 3, _callsign, _unit_position select 5, _unit_position select 6];
|
||||||
|
|
||||||
|
"armatak" callExtension ["tcp_socket:cot:marker", [_marker_cot]];
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
// function name: armatak_fnc_extract_eud_cot_info
|
// function name: armatak_fnc_send_eud_cot
|
||||||
// function author: Valmo
|
// function author: Valmo
|
||||||
// function description: Gets the information necessary for generating the EUD Cursor Over Time
|
// function description: Gets the information necessary for generating the EUD Cursor Over Time
|
||||||
|
|
||||||
@@ -8,6 +8,5 @@ _position = _unit call armatak_client_fnc_extractClientPosition;
|
|||||||
|
|
||||||
_uuid = _unit call armatak_fnc_extract_uuid;
|
_uuid = _unit call armatak_fnc_extract_uuid;
|
||||||
|
|
||||||
_eud_cot = [_uuid, _position select 0, _position select 1, _position select 2, _callsign, _group_name, _group_role, _position select 3, speed player / 3.6];
|
_eud_cot = [_uuid, _position select 1, _position select 2, _position select 3, _callsign, _group_name, _group_role, _position select 5, _position select 6];
|
||||||
|
"armatak" callExtension ["tcp_socket:cot:eud", [_eud_cot]];
|
||||||
"armatak" callExtension ["tcp_socket:send_eud_cot", [_eud_cot]];
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
params["_group"];
|
params["_group"];
|
||||||
|
|
||||||
{
|
{
|
||||||
_callsign = [_x] call armatak_fnc_extract_callsign;
|
_callsign = [_x] call armatak_fnc_extract_unit_callsign;
|
||||||
_group_name = [_group] call armatak_fnc_extract_group_color;
|
_group_name = [_group] call armatak_fnc_extract_group_color;
|
||||||
_group_role = [_x] call armatak_fnc_extract_group_role;
|
_group_role = [_x] call armatak_fnc_extract_group_role;
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,10 @@
|
|||||||
params ["_unit", "_type", "_callsign"];
|
params ["_unit", "_type", "_callsign"];
|
||||||
|
|
||||||
_unit_position = _unit call armatak_client_fnc_extractClientPosition;
|
_unit_position = _unit call armatak_client_fnc_extractClientPosition;
|
||||||
|
_video_url = [_unit] call armatak_fnc_extract_marker_video_url;
|
||||||
|
|
||||||
_uuid = _unit call armatak_fnc_extract_uuid;
|
_uuid = _unit call armatak_fnc_extract_uuid;
|
||||||
|
|
||||||
_marker_cot = [_uuid, _type, _unit_position select 0, _unit_position select 1, _unit_position select 2, _callsign, _unit_position select 3, speed _unit / 3.6];
|
_marker_cot = [_uuid, _type, _unit_position select 1, _unit_position select 2, _unit_position select 3, _callsign, _unit_position select 5, _unit_position select 6, _video_url];
|
||||||
|
|
||||||
"armatak" callExtension ["tcp_socket:send_marker_cot", [_marker_cot]];
|
"armatak" callExtension ["tcp_socket:cot:marker", [_marker_cot]];
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
|
#include "..\..\script_component.hpp"
|
||||||
|
|
||||||
params["_group"];
|
params["_group"];
|
||||||
|
|
||||||
_group_name = _group getVariable "_atak_group_name";
|
_group_name = _group getVariable QGVAR(group_name);
|
||||||
|
|
||||||
if (isNil "_group_name") then {
|
if (isNil "_group_name") then {
|
||||||
_group_colors = missionNamespace getVariable "armatak_group_colors";
|
_group_colors = missionNamespace getVariable QGVAR(group_colors);
|
||||||
_group_name = selectRandom _group_colors;
|
_group_name = selectRandom _group_colors;
|
||||||
|
|
||||||
if (count _group_colors > 0) then {
|
if (count _group_colors > 0) then {
|
||||||
@@ -14,11 +16,11 @@ if (isNil "_group_name") then {
|
|||||||
_group_colors deleteAt _randomIndex;
|
_group_colors deleteAt _randomIndex;
|
||||||
|
|
||||||
_group_name = _selectedColor;
|
_group_name = _selectedColor;
|
||||||
_group setVariable ["_atak_group_name", _group_name];
|
_group setVariable [QGVAR(group_name), _group_name];
|
||||||
missionNamespace setVariable ["armatak_group_colors", _group_colors]
|
missionNamespace setVariable [QGVAR(group_colors), _group_colors]
|
||||||
} else {
|
} else {
|
||||||
_group_name = "Red";
|
_group_name = "Red";
|
||||||
_group setVariable ["_atak_group_name", _group_name];
|
_group setVariable [QGVAR(group_name), _group_name];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
params["_unit"];
|
params["_unit"];
|
||||||
|
|
||||||
|
_group = group _unit;
|
||||||
_group_roles = ["Team Member", "Team Lead", "HQ", "Sniper", "Medic", "Forward Observer", "RTO", "K9"];
|
_group_roles = ["Team Member", "Team Lead", "HQ", "Sniper", "Medic", "Forward Observer", "RTO", "K9"];
|
||||||
_group_role = "Team Member";
|
_group_role = "Team Member";
|
||||||
|
|
||||||
if (["SpecialOperative", (configFile >> "CfgVehicles" >> typeOf _unit >> "role") call BIS_fnc_getCfgData, false] call BIS_fnc_inString) then {
|
if (["SpecialOperative", (configOf _unit >> "role") call BIS_fnc_getCfgData, false] call BIS_fnc_inString) then {
|
||||||
_group_role = _group_roles select 5;
|
_group_role = _group_roles select 5;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -19,7 +20,7 @@ if (((backpack _unit) isKindOf "TFAR_Bag_Base") or (["radio", typeOf _unit, fals
|
|||||||
_group_role = _group_roles select 6;
|
_group_role = _group_roles select 6;
|
||||||
};
|
};
|
||||||
|
|
||||||
if ((["sniper", typeOf _unit, false] call BIS_fnc_inString) or (["marksman", (configFile >> "CfgVehicles" >> typeOf _unit >> "role") call BIS_fnc_getCfgData, false] call BIS_fnc_inString) or (["sharpshooter", typeOf _unit, false] call BIS_fnc_inString)) then {
|
if ((["sniper", typeOf _unit, false] call BIS_fnc_inString) or (["marksman", (configOf _unit >> "role") call BIS_fnc_getCfgData, false] call BIS_fnc_inString) or (["sharpshooter", typeOf _unit, false] call BIS_fnc_inString)) then {
|
||||||
_group_role = _group_roles select 3;
|
_group_role = _group_roles select 3;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -34,7 +35,7 @@ if (["officer", typeOf _unit, false] call BIS_fnc_inString) then {
|
|||||||
_pre_defined_role = _unit getVariable "_atak_group_role";
|
_pre_defined_role = _unit getVariable "_atak_group_role";
|
||||||
|
|
||||||
if (!isNil "_pre_defined_role") then {
|
if (!isNil "_pre_defined_role") then {
|
||||||
_callsign = _pre_defined_callsign;
|
_callsign = _pre_defined_role;
|
||||||
};
|
};
|
||||||
|
|
||||||
_group_role
|
_group_role
|
||||||
@@ -7,15 +7,15 @@ params["_unit"];
|
|||||||
private _callsign = "";
|
private _callsign = "";
|
||||||
|
|
||||||
if ((([_unit] call BIS_fnc_objectType) select 0) == "Vehicle") then {
|
if ((([_unit] call BIS_fnc_objectType) select 0) == "Vehicle") then {
|
||||||
_callsign = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "displayName");
|
_callsign = getText (configOf _unit >> "displayName");
|
||||||
|
|
||||||
if (!isNull driver _unit) then {
|
if (!isNull driver _unit) then {
|
||||||
_callsign = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "displayName") + " | " + ([name (driver _unit)] call armatak_fnc_shorten_name);
|
_callsign = getText (configOf _unit >> "displayName") + " | " + ([name (driver _unit)] call armatak_fnc_shorten_name);
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
if (unitIsUAV _unit) then {
|
if (unitIsUAV _unit) then {
|
||||||
_callsign = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "displayName");
|
_callsign = getText (configOf _unit >> "displayName");
|
||||||
|
|
||||||
if (isUAVConnected _unit) then {
|
if (isUAVConnected _unit) then {
|
||||||
_callsign = (_callsign) + "[ON]";
|
_callsign = (_callsign) + "[ON]";
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// function name: armatak_fnc_extract_marker_video_url
|
||||||
|
// function author: Codex
|
||||||
|
// function description: Gets the marker video URL configured in 3DEN for a vehicle
|
||||||
|
|
||||||
|
params ["_unit"];
|
||||||
|
|
||||||
|
private _videoUrl = _unit getVariable ["armatak_attribute_marker_video_url", ""];
|
||||||
|
|
||||||
|
if (isNil "_videoUrl") exitWith {
|
||||||
|
""
|
||||||
|
};
|
||||||
|
|
||||||
|
_videoUrl
|
||||||
@@ -7,8 +7,15 @@ params["_unit"];
|
|||||||
private _affiliation = "f";
|
private _affiliation = "f";
|
||||||
private _type = "G";
|
private _type = "G";
|
||||||
private _role = "a-f-G-U-C-I";
|
private _role = "a-f-G-U-C-I";
|
||||||
|
private _side = side _unit;
|
||||||
|
|
||||||
switch (str side _unit) do {
|
if (isNil {
|
||||||
|
_unit getVariable "armatak_current_side"
|
||||||
|
}) then {
|
||||||
|
_side = _unit getVariable "armatak_current_side";
|
||||||
|
};
|
||||||
|
|
||||||
|
switch (str _side) do {
|
||||||
case "WEST": {
|
case "WEST": {
|
||||||
_affiliation = "f";
|
_affiliation = "f";
|
||||||
};
|
};
|
||||||
@@ -22,7 +29,7 @@ switch (str side _unit) do {
|
|||||||
_affiliation = "u";
|
_affiliation = "u";
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
_affiliation = "f";
|
_affiliation = "u";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -110,7 +117,6 @@ if ((typeOf (vehicle _unit) != typeOf _unit) or ((_unit_type select 0) == "Vehic
|
|||||||
|
|
||||||
_role = "a-" + _affiliation + "-" + _type;
|
_role = "a-" + _affiliation + "-" + _type;
|
||||||
|
|
||||||
|
|
||||||
armatak_attribute_marker_type = _unit getVariable "armatak_attribute_marker_type";
|
armatak_attribute_marker_type = _unit getVariable "armatak_attribute_marker_type";
|
||||||
|
|
||||||
if (!isNil "armatak_attribute_marker_type" or armatak_attribute_marker_type != '') then {
|
if (!isNil "armatak_attribute_marker_type" or armatak_attribute_marker_type != '') then {
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
params["_unit"];
|
||||||
|
|
||||||
|
_target = getSensorTargets (_unit);
|
||||||
|
|
||||||
|
{
|
||||||
|
_unit = _x select 0;
|
||||||
|
_position = _x select 1;
|
||||||
|
_status = _x select 2;
|
||||||
|
|
||||||
|
if (isNil {
|
||||||
|
_unit getVariable "armatak_current_side"
|
||||||
|
}) then {
|
||||||
|
_unit setVariable ["armatak_current_side", side _unit];
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_status != "destroyed" && !(_unit in armatak_server_syncedUnits)) then {
|
||||||
|
_unit_position = _unit call armatak_client_fnc_extractClientPosition;
|
||||||
|
|
||||||
|
_uuid = _unit call armatak_fnc_extract_uuid;
|
||||||
|
_type = _unit call armatak_fnc_extract_role;
|
||||||
|
_callsign = getText (configOf _unit >> "displayName");
|
||||||
|
|
||||||
|
_marker_cot = [_uuid, _type, _unit_position select 1, _unit_position select 2, _unit_position select 3, _callsign, _unit_position select 5, _unit_position select 6];
|
||||||
|
|
||||||
|
"armatak" callExtension ["tcp_socket:cot:marker", [_marker_cot]];
|
||||||
|
};
|
||||||
|
} forEach _target;
|
||||||
@@ -12,10 +12,14 @@ if (roleDescription _unit != "") then {
|
|||||||
_callsign = name _unit;
|
_callsign = name _unit;
|
||||||
|
|
||||||
if (_callsign == "Error: No unit") then {
|
if (_callsign == "Error: No unit") then {
|
||||||
_callsign = getText (configFile >> "CfgVehicles" >> typeOf _unit >> "displayName");
|
_callsign = getText (configOf _unit >> "displayName");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (side _unit == east) then {
|
||||||
|
_callsign = getText (configOf _unit >> "displayName");
|
||||||
|
};
|
||||||
|
|
||||||
armatak_attribute_unit_callsign = _unit getVariable "armatak_attribute_unit_callsign";
|
armatak_attribute_unit_callsign = _unit getVariable "armatak_attribute_unit_callsign";
|
||||||
|
|
||||||
if (!isNil "armatak_attribute_unit_callsign" or armatak_attribute_unit_callsign != '') then {
|
if (!isNil "armatak_attribute_unit_callsign" or armatak_attribute_unit_callsign != '') then {
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
params[_type, _message];
|
params["_type", "_message"];
|
||||||
|
|
||||||
"armatak" callExtension ["log", [_type, _message]]
|
"armatak" callExtension ["log", [_type, _message]]
|
||||||
23
addons/main/functions/map/fn_convert_to_clafghan.sqf
Normal file
23
addons/main/functions/map/fn_convert_to_clafghan.sqf
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
|
_playerPosition = [_latitude, _longitude, _altitude];
|
||||||
|
|
||||||
|
_playerLatitude = _playerPosition select 0;
|
||||||
|
_playerLongitude = _playerPosition select 1;
|
||||||
|
|
||||||
|
_playerMaxLatitude = 20480;
|
||||||
|
_playerMaxLongitude = 20480;
|
||||||
|
|
||||||
|
_MapMaxLongitude = 33.728772;
|
||||||
|
_MapMinLongitude = 33.542815;
|
||||||
|
|
||||||
|
_MapMaxLatitude = 63.169746;
|
||||||
|
_MapMinLatitude = 62.938820;
|
||||||
|
|
||||||
|
_LongitudeDifference = _MapMaxLongitude - _MapMinLongitude;
|
||||||
|
_LatitudeDifference = _MapMaxLatitude - _MapMinLatitude;
|
||||||
|
|
||||||
|
_RealLongitude = (_playerLongitude / _playerMaxLongitude) * _LongitudeDifference + _MapMinLongitude;
|
||||||
|
_RealLatitude = (_playerLatitude / _playerMaxLatitude) * _LatitudeDifference + _MapMinLatitude;
|
||||||
|
|
||||||
|
[_RealLongitude, _RealLatitude, _playerPosition select 2]
|
||||||
23
addons/main/functions/map/fn_convert_to_colombia.sqf
Normal file
23
addons/main/functions/map/fn_convert_to_colombia.sqf
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
|
_playerPosition = [_latitude, _longitude, _altitude];
|
||||||
|
|
||||||
|
_playerLatitude = _playerPosition select 0;
|
||||||
|
_playerLongitude = _playerPosition select 1;
|
||||||
|
|
||||||
|
_playerMaxLatitude = 20480;
|
||||||
|
_playerMaxLongitude = 20480;
|
||||||
|
|
||||||
|
_MapMaxLatitude = -67.765153;
|
||||||
|
_MapMinLatitude = -68.223664;
|
||||||
|
|
||||||
|
_MapMaxLongitude = 10.593815;
|
||||||
|
_MapMinLongitude = 10.137466;
|
||||||
|
|
||||||
|
_LongitudeDifference = _MapMaxLongitude - _MapMinLongitude;
|
||||||
|
_LatitudeDifference = _MapMaxLatitude - _MapMinLatitude;
|
||||||
|
|
||||||
|
_RealLongitude = (_playerLongitude / _playerMaxLongitude) * _LongitudeDifference + _MapMinLongitude;
|
||||||
|
_RealLatitude = (_playerLatitude / _playerMaxLatitude) * _LatitudeDifference + _MapMinLatitude;
|
||||||
|
|
||||||
|
[_RealLongitude, _RealLatitude, _playerPosition select 2]
|
||||||
30
addons/main/functions/map/fn_convert_to_hellanmaa.sqf
Normal file
30
addons/main/functions/map/fn_convert_to_hellanmaa.sqf
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
|
private _mapWidth = 8192;
|
||||||
|
private _mapHeight = 8192;
|
||||||
|
|
||||||
|
// SW corner (used as origin)
|
||||||
|
private _SW_lat = 63.005389;
|
||||||
|
private _SW_lon = 22.638957;
|
||||||
|
|
||||||
|
// SE corner
|
||||||
|
private _SE_lat = 63.010092;
|
||||||
|
private _SE_lon = 22.800107;
|
||||||
|
|
||||||
|
// NW corner
|
||||||
|
private _NW_lat = 63.078713;
|
||||||
|
private _NW_lon = 22.628542;
|
||||||
|
|
||||||
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _edgeNW_lat = _NW_lat - _SW_lat;
|
||||||
|
private _edgeNW_lon = _NW_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _fx = _longitudeInGame / _mapWidth;
|
||||||
|
private _fy = _latitudeInGame / _mapHeight;
|
||||||
|
|
||||||
|
private _realLat = _SW_lat + (_fx * _edgeSE_lat) + (_fy * _edgeNW_lat);
|
||||||
|
private _realLon = _SW_lon + (_fx * _edgeSE_lon) + (_fy * _edgeNW_lon);
|
||||||
|
|
||||||
|
[_realLat, _realLon, _altitude]
|
||||||
30
addons/main/functions/map/fn_convert_to_kunduz_valley.sqf
Normal file
30
addons/main/functions/map/fn_convert_to_kunduz_valley.sqf
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
|
private _mapWidth = 10240;
|
||||||
|
private _mapHeight = 10240;
|
||||||
|
|
||||||
|
// SW corner (used as origin)
|
||||||
|
private _SW_lat = 36.547662;
|
||||||
|
private _SW_lon = 68.802314;
|
||||||
|
|
||||||
|
// SE corner
|
||||||
|
private _SE_lat = 36.547662;
|
||||||
|
private _SE_lon = 68.916671;
|
||||||
|
|
||||||
|
// NW corner
|
||||||
|
private _NW_lat = 36.639935;
|
||||||
|
private _NW_lon = 68.802314;
|
||||||
|
|
||||||
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _edgeNW_lat = _NW_lat - _SW_lat;
|
||||||
|
private _edgeNW_lon = _NW_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _fx = _longitudeInGame / _mapWidth;
|
||||||
|
private _fy = _latitudeInGame / _mapHeight;
|
||||||
|
|
||||||
|
private _realLat = _SW_lat + (_fx * _edgeSE_lat) + (_fy * _edgeNW_lat);
|
||||||
|
private _realLon = _SW_lon + (_fx * _edgeSE_lon) + (_fy * _edgeNW_lon);
|
||||||
|
|
||||||
|
[_realLat, _realLon, _altitude]
|
||||||
23
addons/main/functions/map/fn_convert_to_lawn.sqf
Normal file
23
addons/main/functions/map/fn_convert_to_lawn.sqf
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
|
_playerPosition = [_latitude, _longitude, _altitude];
|
||||||
|
|
||||||
|
_playerLatitude = _playerPosition select 0;
|
||||||
|
_playerLongitude = _playerPosition select 1;
|
||||||
|
|
||||||
|
_playerMaxLongitude = 4992;
|
||||||
|
_playerMaxLatitude = 4992;
|
||||||
|
|
||||||
|
_MapMaxLongitude = -99.722665;
|
||||||
|
_MapMinLongitude = -99.775505;
|
||||||
|
|
||||||
|
_MapMaxLatitude = 32.159272;
|
||||||
|
_MapMinLatitude = 32.114011;
|
||||||
|
|
||||||
|
_LongitudeDifference = _MapMaxLongitude - _MapMinLongitude;
|
||||||
|
_LatitudeDifference = _MapMaxLatitude - _MapMinLatitude;
|
||||||
|
|
||||||
|
_RealLongitude = (_playerLongitude / _playerMaxLongitude) * _LongitudeDifference + _MapMinLongitude;
|
||||||
|
_RealLatitude = (_playerLatitude / _playerMaxLatitude) * _LatitudeDifference + _MapMinLatitude;
|
||||||
|
|
||||||
|
[_RealLongitude, _RealLatitude, _playerPosition select 2]
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
|
private _mapWidth = 11264;
|
||||||
|
private _mapHeight = 11264;
|
||||||
|
|
||||||
|
// SW corner (used as origin)
|
||||||
|
private _SW_lat = -51.736078;
|
||||||
|
private _SW_lon = -57.915032;
|
||||||
|
|
||||||
|
// SE corner
|
||||||
|
private _SE_lat = -51.736078;
|
||||||
|
private _SE_lon = -58.077879;
|
||||||
|
|
||||||
|
// NW corner
|
||||||
|
private _NW_lat = -51.634750;
|
||||||
|
private _NW_lon = -58.077879;
|
||||||
|
|
||||||
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _edgeNW_lat = _NW_lat - _SW_lat;
|
||||||
|
private _edgeNW_lon = _NW_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _fx = _longitudeInGame / _mapWidth;
|
||||||
|
private _fy = _latitudeInGame / _mapHeight;
|
||||||
|
|
||||||
|
private _realLat = _SW_lat + (_fx * _edgeSE_lat) + (_fy * _edgeNW_lat);
|
||||||
|
private _realLon = _SW_lon + (_fx * _edgeSE_lon) + (_fy * _edgeNW_lon);
|
||||||
|
|
||||||
|
[_realLat, _realLon, _altitude]
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
|
private _mapWidth = 16384;
|
||||||
|
private _mapHeight = 16384;
|
||||||
|
|
||||||
|
// SW corner (used as origin)
|
||||||
|
private _SW_lat = -51.806546;
|
||||||
|
private _SW_lon = -57.939747;
|
||||||
|
|
||||||
|
// SE corner
|
||||||
|
private _SE_lat = -51.806546;
|
||||||
|
private _SE_lon = -57.701978;
|
||||||
|
|
||||||
|
// NW corner
|
||||||
|
private _NW_lat = -51.658913;
|
||||||
|
private _NW_lon = -57.939747;
|
||||||
|
|
||||||
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _edgeNW_lat = _NW_lat - _SW_lat;
|
||||||
|
private _edgeNW_lon = _NW_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _fx = _longitudeInGame / _mapWidth;
|
||||||
|
private _fy = _latitudeInGame / _mapHeight;
|
||||||
|
|
||||||
|
private _realLat = _SW_lat + (_fx * _edgeSE_lat) + (_fy * _edgeNW_lat);
|
||||||
|
private _realLon = _SW_lon + (_fx * _edgeSE_lon) + (_fy * _edgeNW_lon);
|
||||||
|
|
||||||
|
[_realLat, _realLon, _altitude]
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
|
private _mapWidth = 10240;
|
||||||
|
private _mapHeight = 10240;
|
||||||
|
|
||||||
|
// SW corner (used as origin)
|
||||||
|
private _SW_lat = -51.863358;
|
||||||
|
private _SW_lon = -59.054585;
|
||||||
|
|
||||||
|
// SE corner
|
||||||
|
private _SE_lat = -51.863358;
|
||||||
|
private _SE_lon = -58.906155;
|
||||||
|
|
||||||
|
// NW corner
|
||||||
|
private _NW_lat = -51.771493;
|
||||||
|
private _NW_lon = -59.054585;
|
||||||
|
|
||||||
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _edgeNW_lat = _NW_lat - _SW_lat;
|
||||||
|
private _edgeNW_lon = _NW_lon - _SW_lon;
|
||||||
|
|
||||||
|
private _fx = _longitudeInGame / _mapWidth;
|
||||||
|
private _fy = _latitudeInGame / _mapHeight;
|
||||||
|
|
||||||
|
private _realLat = _SW_lat + (_fx * _edgeSE_lat) + (_fy * _edgeNW_lat);
|
||||||
|
private _realLon = _SW_lon + (_fx * _edgeSE_lon) + (_fy * _edgeNW_lon);
|
||||||
|
|
||||||
|
[_realLat, _realLon, _altitude]
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
|
_playerPosition = [_latitude, _longitude, _altitude];
|
||||||
|
|
||||||
|
_playerLatitude = _playerPosition select 0;
|
||||||
|
_playerLongitude = _playerPosition select 1;
|
||||||
|
|
||||||
|
_playerMaxLongitude = 5120;
|
||||||
|
_playerMaxLatitude = 5120;
|
||||||
|
|
||||||
|
_MapMaxLatitude = -51.619725;
|
||||||
|
_MapMinLatitude = -51.664223;
|
||||||
|
|
||||||
|
_MapMaxLongitude = -58.394630;
|
||||||
|
_MapMinLongitude = -58.469580;
|
||||||
|
|
||||||
|
_LongitudeDifference = _MapMaxLongitude - _MapMinLongitude;
|
||||||
|
_LatitudeDifference = _MapMaxLatitude - _MapMinLatitude;
|
||||||
|
|
||||||
|
_RealLongitude = (_playerLongitude / _playerMaxLongitude) * _LongitudeDifference + _MapMinLongitude;
|
||||||
|
_RealLatitude = (_playerLatitude / _playerMaxLatitude) * _LatitudeDifference + _MapMinLatitude;
|
||||||
|
|
||||||
|
[_RealLongitude, _RealLatitude, _playerPosition select 2]
|
||||||
23
addons/main/functions/map/fn_convert_to_rut_mandol.sqf
Normal file
23
addons/main/functions/map/fn_convert_to_rut_mandol.sqf
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
|
_playerPosition = [_latitude, _longitude, _altitude];
|
||||||
|
|
||||||
|
_playerLatitude = _playerPosition select 0;
|
||||||
|
_playerLongitude = _playerPosition select 1;
|
||||||
|
|
||||||
|
_playerMaxLatitude = 32768;
|
||||||
|
_playerMaxLongitude = 32768;
|
||||||
|
|
||||||
|
_MapMaxLongitude = 35.285485;
|
||||||
|
_MapMinLongitude = 34.927617;
|
||||||
|
|
||||||
|
_MapMaxLatitude = 70.445404;
|
||||||
|
_MapMinLatitude = 70.016783;
|
||||||
|
|
||||||
|
_LongitudeDifference = _MapMaxLongitude - _MapMinLongitude;
|
||||||
|
_LatitudeDifference = _MapMaxLatitude - _MapMinLatitude;
|
||||||
|
|
||||||
|
_RealLongitude = (_playerLongitude / _playerMaxLongitude) * _LongitudeDifference + _MapMinLongitude;
|
||||||
|
_RealLatitude = (_playerLatitude / _playerMaxLatitude) * _LatitudeDifference + _MapMinLatitude;
|
||||||
|
|
||||||
|
[_RealLongitude, _RealLatitude, _playerPosition select 2]
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
private _mapWidth = 30720;
|
private _mapWidth = 8192;
|
||||||
private _mapHeight = 30720;
|
private _mapHeight = 8192;
|
||||||
|
|
||||||
// SW corner (used as origin)
|
// SW corner (used as origin)
|
||||||
private _SW_lat = 39.456910;
|
private _SW_lat = 39.458019;
|
||||||
private _SW_lon = 24.940792;
|
private _SW_lon = 24.939314;
|
||||||
|
|
||||||
// SE corner
|
// SE corner
|
||||||
private _SE_lat = 39.459151;
|
private _SE_lat = 39.458019;
|
||||||
private _SE_lon = 25.083440;
|
private _SE_lon = 25.081992;
|
||||||
|
|
||||||
// NW corner
|
// NW corner
|
||||||
private _NW_lat = 39.567714;
|
private _NW_lat = 39.568847;
|
||||||
private _NW_lon = 24.937866;
|
private _NW_lon = 24.939314;
|
||||||
|
|
||||||
private _edgeSE_lat = _SE_lat - _SW_lat;
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
private _edgeSE_lon = _SE_lon - _SW_lon;
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
params ["_longitudeInGame", "_latitudeInGame", "_altitude"];
|
||||||
|
|
||||||
private _mapWidth = 30720;
|
private _mapWidth = 15360;
|
||||||
private _mapHeight = 30720;
|
private _mapHeight = 15360;
|
||||||
|
|
||||||
// SW corner (used as origin)
|
// SW corner (used as origin)
|
||||||
private _SW_lat = -19.086825;
|
private _SW_lat = -19.086803;
|
||||||
private _SW_lon = 176.812772;
|
private _SW_lon = 176.812619;
|
||||||
|
|
||||||
// SE corner
|
// SE corner
|
||||||
private _SE_lat = -19.086825;
|
private _SE_lat = -19.086803;
|
||||||
private _SE_lon = 178.687920;
|
private _SE_lon = 178.704583;
|
||||||
|
|
||||||
// NW corner
|
// NW corner
|
||||||
private _NW_lat = -17.196898;
|
private _NW_lat = -17.196900;
|
||||||
private _NW_lon = 176.812622;
|
private _NW_lon = 176.812619;
|
||||||
|
|
||||||
private _edgeSE_lat = _SE_lat - _SW_lat;
|
private _edgeSE_lat = _SE_lat - _SW_lat;
|
||||||
private _edgeSE_lon = _SE_lon - _SW_lon;
|
private _edgeSE_lon = _SE_lon - _SW_lon;
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
params["_latitude", "_longitude", "_altitude"];
|
||||||
|
|
||||||
|
_playerPosition = [_latitude, _longitude, _altitude];
|
||||||
|
|
||||||
|
_playerLatitude = _playerPosition select 0;
|
||||||
|
_playerLongitude = _playerPosition select 1;
|
||||||
|
|
||||||
|
_playerMaxLongitude = 20480;
|
||||||
|
_playerMaxLatitude = 20480;
|
||||||
|
|
||||||
|
_MapMaxLongitude = 48.351216;
|
||||||
|
_MapMinLongitude = 48.097496;
|
||||||
|
|
||||||
|
_MapMaxLatitude = 38.345389;
|
||||||
|
_MapMinLatitude = 37.956754;
|
||||||
|
|
||||||
|
_LongitudeDifference = _MapMaxLongitude - _MapMinLongitude;
|
||||||
|
_LatitudeDifference = _MapMaxLatitude - _MapMinLatitude;
|
||||||
|
|
||||||
|
_RealLongitude = (_playerLongitude / _playerMaxLongitude) * _LongitudeDifference + _MapMinLongitude;
|
||||||
|
_RealLatitude = (_playerLatitude / _playerMaxLatitude) * _LatitudeDifference + _MapMinLatitude;
|
||||||
|
|
||||||
|
[_RealLongitude, _RealLatitude, _playerPosition select 2]
|
||||||
@@ -1,22 +1,11 @@
|
|||||||
class CfgVehicles {
|
class CfgVehicles {
|
||||||
class Logic;
|
class Logic;
|
||||||
class Module_F : Logic
|
class Module_F : Logic {
|
||||||
{
|
class AttributesBase {
|
||||||
class AttributesBase
|
|
||||||
{
|
|
||||||
class Default;
|
|
||||||
class Edit;
|
class Edit;
|
||||||
class Combo;
|
|
||||||
class Checkbox;
|
|
||||||
class CheckboxNumber;
|
|
||||||
class ModuleDescription;
|
class ModuleDescription;
|
||||||
class Units;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ModuleDescription
|
|
||||||
{
|
|
||||||
class AnyBrain;
|
|
||||||
};
|
};
|
||||||
|
class ModuleDescription;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GVAR(moduleBase): Module_F {
|
class GVAR(moduleBase): Module_F {
|
||||||
@@ -30,13 +19,10 @@ class CfgVehicles {
|
|||||||
scopeCurator = 2;
|
scopeCurator = 2;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GVAR(coreModule): GVAR(moduleBase) {
|
class GVAR(connectionModuleBase): GVAR(moduleBase) {
|
||||||
scope = 2;
|
|
||||||
scopeCurator = 0;
|
scopeCurator = 0;
|
||||||
displayname = "CoT Router";
|
|
||||||
icon = "\a3\Modules_F_Curator\Data\iconRadio_ca.paa";
|
icon = "\a3\Modules_F_Curator\Data\iconRadio_ca.paa";
|
||||||
category = QEGVAR(main,moduleCategory);
|
category = QEGVAR(main,moduleCategory);
|
||||||
function = QFUNC(3denCoreModuleConfig);
|
|
||||||
functionPriority = 1;
|
functionPriority = 1;
|
||||||
isGlobal = 0;
|
isGlobal = 0;
|
||||||
isTriggerActivated = 1;
|
isTriggerActivated = 1;
|
||||||
@@ -47,19 +33,25 @@ class CfgVehicles {
|
|||||||
canSetArea = 0;
|
canSetArea = 0;
|
||||||
canSetAreaShape = 0;
|
canSetAreaShape = 0;
|
||||||
canSetAreaHeight = 0;
|
canSetAreaHeight = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GVAR(tcpModule): GVAR(connectionModuleBase) {
|
||||||
|
scope = 2;
|
||||||
|
displayName = "CoT Router (TCP)";
|
||||||
|
function = QFUNC(3denTcpModuleConfig);
|
||||||
|
|
||||||
class Attributes: AttributesBase {
|
class Attributes: AttributesBase {
|
||||||
class GVAR(moduleInstanceAddress): Edit {
|
class GVAR(moduleInstanceAddress): Edit {
|
||||||
property = QGVAR(moduleInstanceAddress);
|
property = QGVAR(moduleInstanceAddress);
|
||||||
displayname = "TAK Server Address";
|
displayName = "TAK Server Address";
|
||||||
tooltip = "TAK Server Instance Address";
|
tooltip = "Hostname or IP address for the TAK or IronTAK server.";
|
||||||
typeName = "STRING";
|
typeName = "STRING";
|
||||||
defaultValue = "localhost";
|
defaultValue = "'localhost'";
|
||||||
};
|
};
|
||||||
class GVAR(moduleInstancePort): Edit {
|
class GVAR(moduleInstancePort): Edit {
|
||||||
property = QGVAR(moduleInstancePort);
|
property = QGVAR(moduleInstancePort);
|
||||||
displayname = "TAK Server TCP Port";
|
displayName = "TAK Server TCP Port";
|
||||||
tooltip = "TAK Server instance Port for TCP connection";
|
tooltip = "Port for the unauthenticated TCP socket.";
|
||||||
typeName = "NUMBER";
|
typeName = "NUMBER";
|
||||||
defaultValue = "8088";
|
defaultValue = "8088";
|
||||||
};
|
};
|
||||||
@@ -67,17 +59,68 @@ class CfgVehicles {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ModuleDescription: ModuleDescription {
|
class ModuleDescription: ModuleDescription {
|
||||||
description = "Generate the initial ARMATAK configuration, syncronizing all players to the TAK server instance";
|
description = "Connect ArmaTAK to a TAK server over plain TCP.";
|
||||||
sync[] = {"LocationArea_F"};
|
sync[] = {"LocationArea_F"};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
class GVAR(coreModuleCurator): GVAR(coreModule) {
|
class GVAR(enrollModule): GVAR(connectionModuleBase) {
|
||||||
|
scope = 2;
|
||||||
|
displayName = "CoT Router (Authenticated)";
|
||||||
|
function = QFUNC(3denEnrollModuleConfig);
|
||||||
|
|
||||||
|
class Attributes: AttributesBase {
|
||||||
|
class GVAR(moduleInstanceAddress): Edit {
|
||||||
|
property = QGVAR(moduleInstanceAddress);
|
||||||
|
displayname = "TAK Server Address";
|
||||||
|
tooltip = "Hostname or IP address used for enrollment and the final TLS connection.";
|
||||||
|
typeName = "STRING";
|
||||||
|
defaultValue = "'localhost'";
|
||||||
|
};
|
||||||
|
class GVAR(moduleEnrollmentPort): Edit {
|
||||||
|
property = QGVAR(moduleEnrollmentPort);
|
||||||
|
displayName = "Enrollment HTTPS Port";
|
||||||
|
tooltip = "Port used for GET /Marti/api/tls/config and POST /Marti/api/tls/signClient/v2.";
|
||||||
|
typeName = "NUMBER";
|
||||||
|
defaultValue = "8446";
|
||||||
|
};
|
||||||
|
class GVAR(moduleEnrollmentUsername): Edit {
|
||||||
|
property = QGVAR(moduleEnrollmentUsername);
|
||||||
|
displayName = "Enrollment Username";
|
||||||
|
tooltip = "Username used in Basic Auth for client certificate enrollment.";
|
||||||
|
typeName = "STRING";
|
||||||
|
defaultValue = "''";
|
||||||
|
};
|
||||||
|
class GVAR(moduleEnrollmentPassword): Edit {
|
||||||
|
property = QGVAR(moduleEnrollmentPassword);
|
||||||
|
displayName = "Enrollment Password";
|
||||||
|
tooltip = "Password used in Basic Auth for client certificate enrollment.";
|
||||||
|
typeName = "STRING";
|
||||||
|
defaultValue = "''";
|
||||||
|
};
|
||||||
|
class ModuleDescription: ModuleDescription {};
|
||||||
|
};
|
||||||
|
|
||||||
|
class ModuleDescription: ModuleDescription {
|
||||||
|
description = "Enroll a client certificate and connect ArmaTAK over mTLS.";
|
||||||
|
sync[] = {"LocationArea_F"};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class GVAR(tcpModuleCurator): GVAR(tcpModule) {
|
||||||
scope = 1;
|
scope = 1;
|
||||||
scopeCurator = 2;
|
scopeCurator = 2;
|
||||||
function = "";
|
function = "";
|
||||||
displayName = "CoT Router (Zeus)";
|
displayName = "CoT Router (TCP, Zeus)";
|
||||||
curatorInfoType = "armatak_zeus_core_module_dialog";
|
curatorInfoType = "armatak_zeus_tcp_module_dialog";
|
||||||
|
};
|
||||||
|
|
||||||
|
class GVAR(enrollModuleCurator): GVAR(enrollModule) {
|
||||||
|
scope = 1;
|
||||||
|
scopeCurator = 2;
|
||||||
|
function = "";
|
||||||
|
displayName = "CoT Router (Authenticated, Zeus)";
|
||||||
|
curatorInfoType = "armatak_zeus_enroll_module_dialog";
|
||||||
};
|
};
|
||||||
|
|
||||||
class GVAR(markEntity): GVAR(moduleBase) {
|
class GVAR(markEntity): GVAR(moduleBase) {
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
PREP(3denCoreModuleConfig);
|
PREP(3denEnrollModuleConfig);
|
||||||
|
PREP(3denTcpModuleConfig);
|
||||||
PREP(routerEntityAdd);
|
PREP(routerEntityAdd);
|
||||||
PREP(routerEntityRemove);
|
PREP(routerEntityRemove);
|
||||||
PREP(ZeusCoreModuleConfig);
|
PREP(startCotRouter);
|
||||||
|
PREP(ZeusEnrollModuleConfig);
|
||||||
|
PREP(ZeusTcpModuleConfig);
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ class CfgPatches {
|
|||||||
class ADDON {
|
class ADDON {
|
||||||
name = COMPONENT_NAME;
|
name = COMPONENT_NAME;
|
||||||
units[] = {
|
units[] = {
|
||||||
QGVAR(coreModule),
|
QGVAR(tcpModule),
|
||||||
QGVAR(coreModuleCurator),
|
QGVAR(tcpModuleCurator),
|
||||||
|
QGVAR(enrollModule),
|
||||||
|
QGVAR(enrollModuleCurator),
|
||||||
QGVAR(markEntity)
|
QGVAR(markEntity)
|
||||||
};
|
};
|
||||||
weapons[] = {};
|
weapons[] = {};
|
||||||
|
|||||||
@@ -1,104 +1,174 @@
|
|||||||
class RscObject;
|
|
||||||
class RscText;
|
class RscText;
|
||||||
class RscFrame;
|
|
||||||
class RscLine;
|
|
||||||
class RscProgress;
|
|
||||||
class RscPicture;
|
|
||||||
class RscBackground;
|
class RscBackground;
|
||||||
class RscPictureKeepAspect;
|
|
||||||
class RscVideo;
|
|
||||||
class RscHTML;
|
|
||||||
class RscButton;
|
class RscButton;
|
||||||
class RscShortcutButton;
|
|
||||||
class RscEdit;
|
class RscEdit;
|
||||||
class RscCombo;
|
|
||||||
class RscListBox;
|
|
||||||
class RscListNBox;
|
|
||||||
class RscXListBox;
|
|
||||||
class RscTree;
|
|
||||||
class RscSlider;
|
|
||||||
class RscXSliderH;
|
|
||||||
class RscActiveText;
|
|
||||||
class RscActivePicture;
|
|
||||||
class RscActivePictureKeepAspect;
|
|
||||||
class RscStructuredText;
|
|
||||||
class RscToolbox;
|
|
||||||
class RscControlsGroup;
|
|
||||||
class RscControlsGroupNoScrollbars;
|
|
||||||
class RscControlsGroupNoHScrollbars;
|
|
||||||
class RscControlsGroupNoVScrollbars;
|
|
||||||
class RscButtonTextOnly;
|
|
||||||
class RscButtonMenu;
|
|
||||||
class RscButtonMenuOK;
|
|
||||||
class RscButtonMenuCancel;
|
|
||||||
class RscButtonMenuSteam;
|
|
||||||
class RscMapControl;
|
|
||||||
class RscMapControlEmpty;
|
|
||||||
class RscCheckBox;
|
|
||||||
|
|
||||||
class armatak_zeus_core_module_dialog {
|
class armatak_zeus_tcp_module_dialog {
|
||||||
idd = 999991;
|
idd = 999991;
|
||||||
movingEnable = 0;
|
movingEnable = 0;
|
||||||
class ControlsBackground {
|
class ControlsBackground {
|
||||||
class armatak_gui_module_zeus_core_dialog_main_frame: RscBackground {
|
class main_frame: RscBackground {
|
||||||
idc = 1800;
|
idc = 1800;
|
||||||
x = "0.386562 * safezoneW + safezoneX";
|
x = "0.386562 * safezoneW + safezoneX";
|
||||||
y = "0.401 * safezoneH + safezoneY";
|
y = "0.29 * safezoneH + safezoneY";
|
||||||
w = "0.216563 * safezoneW";
|
w = "0.216563 * safezoneW";
|
||||||
h = "0.242 * safezoneH";
|
h = "0.32 * safezoneH";
|
||||||
colorBackground[]={0,0,0,0.45};
|
colorBackground[] = {0,0,0,0.45};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
class Controls {
|
class Controls {
|
||||||
class armatak_gui_module_zeus_core_dialog_address_edit: RscEdit {
|
class address_text: RscText {
|
||||||
idc = 14000;
|
|
||||||
text = "localhost";
|
|
||||||
x = "0.391719 * safezoneW + safezoneX";
|
|
||||||
y = "0.445 * safezoneH + safezoneY";
|
|
||||||
w = "0.20625 * safezoneW";
|
|
||||||
h = "0.044 * safezoneH";
|
|
||||||
colorBackground[]={0,0,0,0.5};
|
|
||||||
};
|
|
||||||
class armatak_gui_module_zeus_core_dialog_address_port_edit: RscEdit {
|
|
||||||
idc = 14001;
|
|
||||||
text = "8088";
|
|
||||||
x = "0.391719 * safezoneW + safezoneX";
|
|
||||||
y = "0.522 * safezoneH + safezoneY";
|
|
||||||
w = "0.20625 * safezoneW";
|
|
||||||
h = "0.044 * safezoneH";
|
|
||||||
colorBackground[]={0,0,0,0.5};
|
|
||||||
};
|
|
||||||
class armatak_gui_module_zeus_core_dialog_address_text: RscText {
|
|
||||||
idc = 1000;
|
idc = 1000;
|
||||||
text = "TAK Server Address";
|
text = "TAK Server Address";
|
||||||
x = "0.391719 * safezoneW + safezoneX";
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
y = "0.412 * safezoneH + safezoneY";
|
y = "0.332 * safezoneH + safezoneY";
|
||||||
w = "0.20625 * safezoneW";
|
w = "0.20625 * safezoneW";
|
||||||
h = "0.033 * safezoneH";
|
h = "0.033 * safezoneH";
|
||||||
};
|
};
|
||||||
class armatak_gui_module_zeus_core_dialog_address_port_text: RscText {
|
class address_edit: RscEdit {
|
||||||
|
idc = 14000;
|
||||||
|
text = "localhost";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.365 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class port_text: RscText {
|
||||||
idc = 1001;
|
idc = 1001;
|
||||||
text = "TAK Server Port";
|
text = "TAK Server Port";
|
||||||
x = "0.391719 * safezoneW + safezoneX";
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
y = "0.489 * safezoneH + safezoneY";
|
y = "0.425 * safezoneH + safezoneY";
|
||||||
w = "0.20625 * safezoneW";
|
w = "0.20625 * safezoneW";
|
||||||
h = "0.033 * safezoneH";
|
h = "0.033 * safezoneH";
|
||||||
};
|
};
|
||||||
class armatak_gui_module_zeus_core_dialog_address_button_cancel: RscButton {
|
class port_edit: RscEdit {
|
||||||
|
idc = 14001;
|
||||||
|
text = "8088";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.458 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class button_cancel: RscButton {
|
||||||
idc = 1601;
|
idc = 1601;
|
||||||
text = "Cancel";
|
text = "Cancel";
|
||||||
action = "closeDialog 2;";
|
action = "closeDialog 2;";
|
||||||
x = "0.551563 * safezoneW + safezoneX";
|
x = "0.551563 * safezoneW + safezoneX";
|
||||||
y = "0.577 * safezoneH + safezoneY";
|
y = "0.535 * safezoneH + safezoneY";
|
||||||
w = "0.0464063 * safezoneW";
|
w = "0.0464063 * safezoneW";
|
||||||
h = "0.055 * safezoneH";
|
h = "0.055 * safezoneH";
|
||||||
};
|
};
|
||||||
class armatak_gui_module_zeus_core_dialog_address_button_ok: RscButton {
|
class button_ok: RscButton {
|
||||||
idc = 1600;
|
idc = 1600;
|
||||||
text = "Ok";
|
text = "Ok";
|
||||||
action = QUOTE(call FUNC(zeusCoreModuleConfig));
|
action = QUOTE(call FUNC(ZeusTcpModuleConfig));
|
||||||
x = "0.5 * safezoneW + safezoneX";
|
x = "0.5 * safezoneW + safezoneX";
|
||||||
y = "0.577 * safezoneH + safezoneY";
|
y = "0.535 * safezoneH + safezoneY";
|
||||||
|
w = "0.0464063 * safezoneW";
|
||||||
|
h = "0.055 * safezoneH";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
class armatak_zeus_enroll_module_dialog {
|
||||||
|
idd = 999992;
|
||||||
|
movingEnable = 0;
|
||||||
|
class ControlsBackground {
|
||||||
|
class main_frame: RscBackground {
|
||||||
|
idc = 1810;
|
||||||
|
x = "0.386562 * safezoneW + safezoneX";
|
||||||
|
y = "0.2 * safezoneH + safezoneY";
|
||||||
|
w = "0.216563 * safezoneW";
|
||||||
|
h = "0.52 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.45};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
class Controls {
|
||||||
|
class address_text: RscText {
|
||||||
|
idc = 1010;
|
||||||
|
text = "TAK Server Address";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.242 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.033 * safezoneH";
|
||||||
|
};
|
||||||
|
class address_edit: RscEdit {
|
||||||
|
idc = 14100;
|
||||||
|
text = "localhost";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.275 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class enroll_port_text: RscText {
|
||||||
|
idc = 1011;
|
||||||
|
text = "Enrollment HTTPS Port";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.335 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.033 * safezoneH";
|
||||||
|
};
|
||||||
|
class enroll_port_edit: RscEdit {
|
||||||
|
idc = 14101;
|
||||||
|
text = "8446";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.368 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class username_text: RscText {
|
||||||
|
idc = 1012;
|
||||||
|
text = "Enrollment Username";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.428 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.033 * safezoneH";
|
||||||
|
};
|
||||||
|
class username_edit: RscEdit {
|
||||||
|
idc = 14102;
|
||||||
|
text = "";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.461 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class password_text: RscText {
|
||||||
|
idc = 1013;
|
||||||
|
text = "Enrollment Password";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.521 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.033 * safezoneH";
|
||||||
|
};
|
||||||
|
class password_edit: RscEdit {
|
||||||
|
idc = 14103;
|
||||||
|
text = "";
|
||||||
|
x = "0.391719 * safezoneW + safezoneX";
|
||||||
|
y = "0.554 * safezoneH + safezoneY";
|
||||||
|
w = "0.20625 * safezoneW";
|
||||||
|
h = "0.044 * safezoneH";
|
||||||
|
colorBackground[] = {0,0,0,0.5};
|
||||||
|
};
|
||||||
|
class button_cancel: RscButton {
|
||||||
|
idc = 1611;
|
||||||
|
text = "Cancel";
|
||||||
|
action = "closeDialog 2;";
|
||||||
|
x = "0.551563 * safezoneW + safezoneX";
|
||||||
|
y = "0.645 * safezoneH + safezoneY";
|
||||||
|
w = "0.0464063 * safezoneW";
|
||||||
|
h = "0.055 * safezoneH";
|
||||||
|
};
|
||||||
|
class button_ok: RscButton {
|
||||||
|
idc = 1610;
|
||||||
|
text = "Ok";
|
||||||
|
action = QUOTE(call FUNC(ZeusEnrollModuleConfig));
|
||||||
|
x = "0.5 * safezoneW + safezoneX";
|
||||||
|
y = "0.645 * safezoneH + safezoneY";
|
||||||
w = "0.0464063 * safezoneW";
|
w = "0.0464063 * safezoneW";
|
||||||
h = "0.055 * safezoneH";
|
h = "0.055 * safezoneH";
|
||||||
};
|
};
|
||||||
@@ -110,7 +180,7 @@ class armatak_zeus_custom_marker_dialog {
|
|||||||
movingEnable = 0;
|
movingEnable = 0;
|
||||||
|
|
||||||
class Controls {
|
class Controls {
|
||||||
class RscFrame_1800: RscFrame
|
class RscFrame_1800: RscBackground
|
||||||
{
|
{
|
||||||
idc = 1800;
|
idc = 1800;
|
||||||
x = "0.37625 * safezoneW + safezoneX";
|
x = "0.37625 * safezoneW + safezoneX";
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
|
|
||||||
params [
|
|
||||||
["_logic", objNull, [objNull]],
|
|
||||||
["_units", [], [[]]],
|
|
||||||
["_activated", true, [true]]
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isServer) exitWith {
|
|
||||||
["Connecting to TCP Socket", "success", "TCP Socket"] call EFUNC(main,notify);
|
|
||||||
|
|
||||||
_tak_server_instance_address = _logic getVariable QGVAR(moduleInstanceAddress);
|
|
||||||
_tak_server_instance_port = _logic getVariable QGVAR(moduleInstancePort);
|
|
||||||
|
|
||||||
_tak_server_fulladdress = _tak_server_instance_address + ":" + (str _tak_server_instance_port);
|
|
||||||
|
|
||||||
missionNamespace setVariable ["armatak_server_instance", _tak_server_fulladdress];
|
|
||||||
missionNamespace setVariable ["armatak_tcp_socket_is_running", true];
|
|
||||||
missionNamespace setVariable ["armatak_group_colors", ["White", "Yellow", "Orange", "Magenta", "Red", "Maroon", "Purple", "DarkBlue", "Blue", "Cyan", "Teal", "Green", "DarkGreen", "Brown"]];
|
|
||||||
|
|
||||||
"armatak" callExtension ["tcp_socket:start", [_tak_server_fulladdress]];
|
|
||||||
|
|
||||||
_syncUnits = synchronizedObjects _logic;
|
|
||||||
|
|
||||||
missionNamespace setVariable ["armatak_marked_units", _syncUnits];
|
|
||||||
|
|
||||||
GVAR(syncedUnits) = missionNamespace getVariable "armatak_marked_units";
|
|
||||||
|
|
||||||
[{
|
|
||||||
GVAR(syncedUnits) = missionNamespace getVariable "armatak_marked_units";
|
|
||||||
|
|
||||||
{
|
|
||||||
_objectType = _x call BIS_fnc_objectType;
|
|
||||||
if ((_objectType select 0) == "Soldier") then {
|
|
||||||
_callsign = [_x] call armatak_fnc_extract_unit_callsign;
|
|
||||||
_group_name = [group _x] call armatak_fnc_extract_group_color;
|
|
||||||
_group_role = [_x] call armatak_fnc_extract_group_role;
|
|
||||||
|
|
||||||
[_x, _callsign, _group_name, _group_role] call armatak_fnc_send_eud_cot;
|
|
||||||
[_x] call armatak_fnc_send_digital_pointer_cot;
|
|
||||||
};
|
|
||||||
if ((_objectType select 0) == "Vehicle") then {
|
|
||||||
_atak_type = [_x] call armatak_fnc_extract_role;
|
|
||||||
_callsign = [_x] call armatak_fnc_extract_marker_callsign;
|
|
||||||
|
|
||||||
[_x, _atak_type, _callsign] call armatak_fnc_send_marker_cot;
|
|
||||||
};
|
|
||||||
if (unitIsUAV _x) then {
|
|
||||||
[_x] call armatak_fnc_send_drone_cot;
|
|
||||||
[_x] call armatak_fnc_send_digital_pointer_cot;
|
|
||||||
};
|
|
||||||
} forEach GVAR(syncedUnits);
|
|
||||||
}, 2, []] call CBA_fnc_addPerFrameHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
true;
|
|
||||||
37
addons/server/functions/fnc_3denEnrollModuleConfig.sqf
Normal file
37
addons/server/functions/fnc_3denEnrollModuleConfig.sqf
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
params [
|
||||||
|
["_logic", objNull, [objNull]],
|
||||||
|
["_units", [], [[]]],
|
||||||
|
["_activated", true, [true]]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isServer) exitWith {
|
||||||
|
if (missionNamespace getVariable ["armatak_tcp_socket_is_running", false]) exitWith {
|
||||||
|
["Socket was called twice", "error", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
};
|
||||||
|
|
||||||
|
["Connecting to authenticated TAK socket", "success", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
|
||||||
|
_tak_server_instance_address = _logic getVariable [QGVAR(moduleInstanceAddress), "localhost"];
|
||||||
|
_tak_server_enrollment_port = _logic getVariable [QGVAR(moduleEnrollmentPort), 8446];
|
||||||
|
_tak_server_enrollment_username = _logic getVariable [QGVAR(moduleEnrollmentUsername), ""];
|
||||||
|
_tak_server_enrollment_password = _logic getVariable [QGVAR(moduleEnrollmentPassword), ""];
|
||||||
|
|
||||||
|
"armatak" callExtension [
|
||||||
|
"tcp_socket:start_enroll_mtls",
|
||||||
|
[
|
||||||
|
_tak_server_instance_address,
|
||||||
|
_tak_server_instance_address,
|
||||||
|
str _tak_server_enrollment_port,
|
||||||
|
_tak_server_enrollment_username,
|
||||||
|
_tak_server_enrollment_password,
|
||||||
|
""
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
missionNamespace setVariable ["armatak_server_syncedUnits", synchronizedObjects _logic];
|
||||||
|
_tak_server_instance_address call FUNC(startCotRouter);
|
||||||
|
};
|
||||||
|
|
||||||
|
true
|
||||||
26
addons/server/functions/fnc_3denTcpModuleConfig.sqf
Normal file
26
addons/server/functions/fnc_3denTcpModuleConfig.sqf
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
params [
|
||||||
|
["_logic", objNull, [objNull]],
|
||||||
|
["_units", [], [[]]],
|
||||||
|
["_activated", true, [true]]
|
||||||
|
];
|
||||||
|
|
||||||
|
if (isServer) exitWith {
|
||||||
|
if (missionNamespace getVariable ["armatak_tcp_socket_is_running", false]) exitWith {
|
||||||
|
["Socket was called twice", "error", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
};
|
||||||
|
|
||||||
|
["Connecting to TCP Socket", "success", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
|
||||||
|
_tak_server_instance_address = _logic getVariable [QGVAR(moduleInstanceAddress), "localhost"];
|
||||||
|
_tak_server_instance_port = _logic getVariable [QGVAR(moduleInstancePort), 8088];
|
||||||
|
_tak_server_fulladdress = _tak_server_instance_address + ":" + (str _tak_server_instance_port);
|
||||||
|
|
||||||
|
"armatak" callExtension ["tcp_socket:start", [_tak_server_fulladdress]];
|
||||||
|
|
||||||
|
missionNamespace setVariable ["armatak_server_syncedUnits", synchronizedObjects _logic];
|
||||||
|
_tak_server_fulladdress call FUNC(startCotRouter);
|
||||||
|
};
|
||||||
|
|
||||||
|
true
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
|
|
||||||
params ["_logic"];
|
|
||||||
|
|
||||||
_socket_is_running = missionNamespace getVariable ["armatak_tcp_socket_is_running", false];
|
|
||||||
|
|
||||||
if (_socket_is_running) exitWith {
|
|
||||||
["Socket was called twice","error", "TCP Socket"] call EFUNC(main,notify);
|
|
||||||
closeDialog 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
disableSerialization;
|
|
||||||
|
|
||||||
["Connecting to TCP Socket", "success", "TCP Socket"] call EFUNC(main,notify);
|
|
||||||
|
|
||||||
_tak_server_instance_address = ctrlText 14000;
|
|
||||||
_tak_server_instance_port = ctrlText 14001;
|
|
||||||
|
|
||||||
_tak_server_fulladdress = ((_tak_server_instance_address) + ":" + (_tak_server_instance_port));
|
|
||||||
|
|
||||||
missionNamespace setVariable ["armatak_server_instance", _tak_server_fulladdress];
|
|
||||||
missionNamespace setVariable ["armatak_tcp_socket_is_running", true];
|
|
||||||
missionNamespace setVariable ["armatak_group_colors", ["White", "Yellow", "Orange", "Magenta", "Red", "Maroon", "Purple", "DarkBlue", "Blue", "Cyan", "Teal", "Green", "DarkGreen", "Brown"]];
|
|
||||||
|
|
||||||
"armatak" callExtension ["tcp_socket:start", [_tak_server_fulladdress]];
|
|
||||||
|
|
||||||
_syncUnits = [];
|
|
||||||
|
|
||||||
missionNamespace setVariable ["armatak_marked_units", _syncUnits];
|
|
||||||
|
|
||||||
GVAR(syncedUnits) = missionNamespace getVariable "armatak_marked_units";
|
|
||||||
|
|
||||||
[{
|
|
||||||
GVAR(syncedUnits) = missionNamespace getVariable "armatak_marked_units";
|
|
||||||
|
|
||||||
{
|
|
||||||
_objectType = _x call BIS_fnc_objectType;
|
|
||||||
if ((_objectType select 0) == "Soldier") then {
|
|
||||||
_callsign = [_x] call armatak_fnc_extract_unit_callsign;
|
|
||||||
_group_name = [group _x] call armatak_fnc_extract_group_color;
|
|
||||||
_group_role = [_x] call armatak_fnc_extract_group_role;
|
|
||||||
|
|
||||||
[_x, _callsign, _group_name, _group_role] call armatak_fnc_send_eud_cot;
|
|
||||||
[_x] call armatak_fnc_send_digital_pointer_cot;
|
|
||||||
};
|
|
||||||
if ((_objectType select 0) == "Vehicle") then {
|
|
||||||
_atak_type = [_x] call armatak_fnc_extract_role;
|
|
||||||
_callsign = [_x] call armatak_fnc_extract_marker_callsign;
|
|
||||||
|
|
||||||
[_x, _atak_type, _callsign] call armatak_fnc_send_marker_cot;
|
|
||||||
};
|
|
||||||
if (unitIsUAV _x) then {
|
|
||||||
[_x] call armatak_fnc_send_drone_cot;
|
|
||||||
[_x] call armatak_fnc_send_digital_pointer_cot;
|
|
||||||
};
|
|
||||||
} forEach GVAR(syncedUnits);
|
|
||||||
}, 2, []] call CBA_fnc_addPerFrameHandler;
|
|
||||||
|
|
||||||
deleteVehicle _logic;
|
|
||||||
closeDialog 1;
|
|
||||||
33
addons/server/functions/fnc_ZeusEnrollModuleConfig.sqf
Normal file
33
addons/server/functions/fnc_ZeusEnrollModuleConfig.sqf
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
params ["_logic"];
|
||||||
|
|
||||||
|
if (missionNamespace getVariable ["armatak_tcp_socket_is_running", false]) exitWith {
|
||||||
|
["Socket was called twice", "error", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
closeDialog 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
disableSerialization;
|
||||||
|
|
||||||
|
["Connecting to authenticated TAK socket", "success", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
|
||||||
|
_tak_server_instance_address = ctrlText 14100;
|
||||||
|
_tak_server_enrollment_port = ctrlText 14101;
|
||||||
|
_tak_server_enrollment_username = ctrlText 14102;
|
||||||
|
_tak_server_enrollment_password = ctrlText 14103;
|
||||||
|
|
||||||
|
"armatak" callExtension [
|
||||||
|
"tcp_socket:start_enroll_mtls",
|
||||||
|
[
|
||||||
|
_tak_server_instance_address,
|
||||||
|
_tak_server_instance_address,
|
||||||
|
_tak_server_enrollment_port,
|
||||||
|
_tak_server_enrollment_username,
|
||||||
|
_tak_server_enrollment_password,
|
||||||
|
""
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
_tak_server_instance_address call FUNC(startCotRouter);
|
||||||
|
deleteVehicle _logic;
|
||||||
|
closeDialog 1;
|
||||||
22
addons/server/functions/fnc_ZeusTcpModuleConfig.sqf
Normal file
22
addons/server/functions/fnc_ZeusTcpModuleConfig.sqf
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
params ["_logic"];
|
||||||
|
|
||||||
|
if (missionNamespace getVariable ["armatak_tcp_socket_is_running", false]) exitWith {
|
||||||
|
["Socket was called twice", "error", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
closeDialog 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
disableSerialization;
|
||||||
|
|
||||||
|
["Connecting to TCP Socket", "success", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
|
||||||
|
_tak_server_instance_address = ctrlText 14000;
|
||||||
|
_tak_server_instance_port = ctrlText 14001;
|
||||||
|
_tak_server_fulladdress = _tak_server_instance_address + ":" + _tak_server_instance_port;
|
||||||
|
|
||||||
|
"armatak" callExtension ["tcp_socket:start", [_tak_server_fulladdress]];
|
||||||
|
|
||||||
|
_tak_server_fulladdress call FUNC(startCotRouter);
|
||||||
|
deleteVehicle _logic;
|
||||||
|
closeDialog 1;
|
||||||
@@ -20,19 +20,24 @@ params ["_logic"];
|
|||||||
if (!local _logic) exitWith {};
|
if (!local _logic) exitWith {};
|
||||||
|
|
||||||
private _unit = attachedTo _logic;
|
private _unit = attachedTo _logic;
|
||||||
deleteVehicle _logic;
|
|
||||||
|
|
||||||
switch (false) do {
|
switch (false) do {
|
||||||
case (!isNull _unit): {
|
case (!isNull _unit): {
|
||||||
deleteVehicle _logic;
|
|
||||||
["Nothing selected", "error", "TCP Socket"] call EFUNC(main,notify);
|
["Nothing selected", "error", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
deleteVehicle _logic;
|
||||||
};
|
};
|
||||||
default {
|
default {
|
||||||
GVAR(syncedUnits) = missionNamespace getVariable "armatak_marked_units";
|
if (_unit in (missionNamespace getVariable ["armatak_server_syncedUnits", []])) exitWith {
|
||||||
|
["Unit already marked", "warning", "TCP Socket"] call EFUNC(main,notify);
|
||||||
|
deleteVehicle _logic;
|
||||||
|
};
|
||||||
|
|
||||||
|
GVAR(syncedUnits) = missionNamespace getVariable "armatak_server_syncedUnits";
|
||||||
|
|
||||||
GVAR(syncedUnits) pushBack _unit;
|
GVAR(syncedUnits) pushBack _unit;
|
||||||
|
|
||||||
missionNamespace setVariable ["armatak_marked_units", GVAR(syncedUnits)];
|
missionNamespace setVariable ["armatak_server_syncedUnits", GVAR(syncedUnits)];
|
||||||
|
SETVAR(_unit,GVAR(isRouting),true);
|
||||||
|
|
||||||
deleteVehicle _logic;
|
deleteVehicle _logic;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ switch (false) do {
|
|||||||
};
|
};
|
||||||
} forEach GVAR(syncedUnits);
|
} forEach GVAR(syncedUnits);
|
||||||
|
|
||||||
missionNmaespace setVariable ["armatak_marked_units", GVAR(syncedUnits)];
|
missionNamespace setVariable ["armatak_server_syncedUnits", GVAR(syncedUnits)];
|
||||||
|
SETVAR(_unit,GVAR(isRouting),false);
|
||||||
|
|
||||||
deleteVehicle _logic;
|
deleteVehicle _logic;
|
||||||
};
|
};
|
||||||
|
|||||||
47
addons/server/functions/fnc_startCotRouter.sqf
Normal file
47
addons/server/functions/fnc_startCotRouter.sqf
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
#include "..\script_component.hpp"
|
||||||
|
|
||||||
|
params [["_server_instance", "", [""]]];
|
||||||
|
|
||||||
|
missionNamespace setVariable ["armatak_server_instance", _server_instance];
|
||||||
|
missionNamespace setVariable ["armatak_tcp_socket_is_running", true];
|
||||||
|
|
||||||
|
if (isNil { missionNamespace getVariable "armatak_server_syncedUnits" }) then {
|
||||||
|
missionNamespace setVariable ["armatak_server_syncedUnits", []];
|
||||||
|
};
|
||||||
|
|
||||||
|
GVAR(syncedUnits) = missionNamespace getVariable "armatak_server_syncedUnits";
|
||||||
|
|
||||||
|
[{
|
||||||
|
GVAR(syncedUnits) = missionNamespace getVariable "armatak_server_syncedUnits";
|
||||||
|
|
||||||
|
{
|
||||||
|
_objectType = _x call BIS_fnc_objectType;
|
||||||
|
switch (true) do {
|
||||||
|
case ((_objectType select 0) == "Soldier"): {
|
||||||
|
_callsign = [_x] call armatak_fnc_extract_unit_callsign;
|
||||||
|
_group_name = [group _x] call armatak_fnc_extract_group_color;
|
||||||
|
_group_role = [_x] call armatak_fnc_extract_group_role;
|
||||||
|
|
||||||
|
[_x, _callsign, _group_name, _group_role] call armatak_fnc_send_eud_cot;
|
||||||
|
[_x] call armatak_fnc_send_digital_pointer_cot;
|
||||||
|
};
|
||||||
|
case ((_objectType select 0) == "Vehicle"): {
|
||||||
|
_atak_type = [_x] call armatak_fnc_extract_role;
|
||||||
|
_callsign = [_x] call armatak_fnc_extract_marker_callsign;
|
||||||
|
|
||||||
|
[_x, _atak_type, _callsign] call armatak_fnc_send_marker_cot;
|
||||||
|
_x call armatak_fnc_extract_sensor_data;
|
||||||
|
};
|
||||||
|
case ((_objectType select 0) == "VehicleAutonomous"): {
|
||||||
|
_atak_type = [_x] call armatak_fnc_extract_role;
|
||||||
|
_callsign = [_x] call armatak_fnc_extract_marker_callsign;
|
||||||
|
|
||||||
|
[_x, _atak_type, _callsign] call armatak_fnc_send_drone_cot;
|
||||||
|
[_x] call armatak_fnc_send_digital_pointer_cot;
|
||||||
|
_x call armatak_fnc_extract_sensor_data;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} forEach GVAR(syncedUnits);
|
||||||
|
}, 1, []] call CBA_fnc_addPerFrameHandler;
|
||||||
|
|
||||||
|
true
|
||||||
@@ -1 +0,0 @@
|
|||||||
armatak\armatak\addons\video
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
class Extended_PreStart_EventHandlers {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(call COMPILE_SCRIPT(XEH_preStart));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class Extended_PreInit_EventHandlers {
|
|
||||||
class ADDON {
|
|
||||||
init = QUOTE(call COMPILE_SCRIPT(XEH_preInit));
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
class CfgVehicles {
|
|
||||||
class Logic;
|
|
||||||
|
|
||||||
class Module_F : Logic
|
|
||||||
{
|
|
||||||
class AttributesBase
|
|
||||||
{
|
|
||||||
class Default;
|
|
||||||
class Edit;
|
|
||||||
class Combo;
|
|
||||||
class Checkbox;
|
|
||||||
class CheckboxNumber;
|
|
||||||
class ModuleDescription;
|
|
||||||
class Units;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ModuleDescription
|
|
||||||
{
|
|
||||||
class AnyBrain;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
class EGVAR(server,moduleBase);
|
|
||||||
class GVAR(videoModule): EGVAR(server,moduleBase) {
|
|
||||||
scope = 2;
|
|
||||||
scopeCurator = 0;
|
|
||||||
displayname = "Video Streaming Handler";
|
|
||||||
icon = "\a3\Modules_F_Curator\Data\iconRadio_ca.paa";
|
|
||||||
category = QEGVAR(main,moduleCategory);
|
|
||||||
function = QFUNC(videoParser);
|
|
||||||
functionPriority = 1;
|
|
||||||
isGlobal = 0;
|
|
||||||
isTriggerActivated = 1;
|
|
||||||
isDisposable = 1;
|
|
||||||
is3den = 0;
|
|
||||||
curatorCanAttach = 0;
|
|
||||||
curatorInfoType = "RscDisplayAttributeModuleNuke";
|
|
||||||
canSetArea = 0;
|
|
||||||
canSetAreaShape = 0;
|
|
||||||
canSetAreaHeight = 0;
|
|
||||||
|
|
||||||
class Attributes: AttributesBase {
|
|
||||||
class GVAR(instanceAddress): Edit {
|
|
||||||
property = QGVAR(instanceAddress);
|
|
||||||
displayname = "MediaMTX Provider Address";
|
|
||||||
tooltip = "MediaMTX Provider Instance Address";
|
|
||||||
typeName = "STRING";
|
|
||||||
defaultValue = "localhost";
|
|
||||||
};
|
|
||||||
class GVAR(instancePort): Edit {
|
|
||||||
property = "armatak_module_mediamtx_video_stream_instance_port";
|
|
||||||
displayname = "MediaMTX Provider Port";
|
|
||||||
tooltip = "MediaMTX Provider Port for handling video streams";
|
|
||||||
typeName = "STRING";
|
|
||||||
defaultValue = "8554";
|
|
||||||
};
|
|
||||||
class GVAR(instanceAuthUser): Edit {
|
|
||||||
property = QGVAR(instanceAuthUser);
|
|
||||||
displayname = "MediaMTX Provider Username";
|
|
||||||
tooltip = "MediaMTX Provider Instance Username";
|
|
||||||
typeName = "STRING";
|
|
||||||
defaultValue = "administrator";
|
|
||||||
};
|
|
||||||
class GVAR(instanceAuthPassword): Edit {
|
|
||||||
property = QGVAR(instanceAuthPassword);
|
|
||||||
displayname = "MediaMTX Provider Password";
|
|
||||||
tooltip = "MediaMTX Provider Instance Password";
|
|
||||||
typeName = "STRING";
|
|
||||||
defaultValue = "password";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
PREP(videoParser);
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
ADDON = false;
|
|
||||||
|
|
||||||
PREP_RECOMPILE_START;
|
|
||||||
#include "XEH_PREP.hpp"
|
|
||||||
PREP_RECOMPILE_END;
|
|
||||||
|
|
||||||
ADDON = true;
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
#include "XEH_PREP.hpp"
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#include "script_component.hpp"
|
|
||||||
|
|
||||||
class CfgPatches {
|
|
||||||
class ADDON {
|
|
||||||
name = COMPONENT_NAME;
|
|
||||||
units[] = {
|
|
||||||
QGVAR(videoModule)
|
|
||||||
};
|
|
||||||
weapons[] = {};
|
|
||||||
requiredAddons[] = {
|
|
||||||
"cba_main",
|
|
||||||
"ace_main",
|
|
||||||
"armatak_main",
|
|
||||||
"armatak_server"
|
|
||||||
};
|
|
||||||
requiredVersion = REQUIRED_VERSION;
|
|
||||||
author = PROJECT_AUTHOR;
|
|
||||||
url = "https://github.com/valmojr/armatak";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
class CfgMods {
|
|
||||||
class PREFIX {
|
|
||||||
name = "Arma Team Awareness Kit";
|
|
||||||
author = PROJECT_AUTHOR;
|
|
||||||
logo = "logo_ca.paa";
|
|
||||||
logoOver = "logo_hover_ca.paa";
|
|
||||||
tooltip = "ARMATAK";
|
|
||||||
tooltipOwned = "ARMATAK";
|
|
||||||
picture = "picture.paa";
|
|
||||||
actionName = "GitHub";
|
|
||||||
action = "https://github.com/valmojr/armatak";
|
|
||||||
overview = "ARMATAK Addons allows Arma 3 sessions to be parsed to TAK Clients";
|
|
||||||
hideName = 0;
|
|
||||||
hidePicture = 0;
|
|
||||||
dlcColor[] = { 0.23, 0.39, 0.30, 1 };
|
|
||||||
logoSmall = "logo_small_ca.paa";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#include "CfgEventHandlers.hpp"
|
|
||||||
#include "CfgVehicles.hpp"
|
|
||||||
@@ -1,83 +0,0 @@
|
|||||||
#include "..\script_component.hpp"
|
|
||||||
|
|
||||||
params [
|
|
||||||
["_logic", objNull, [objNull]],
|
|
||||||
["_units", [], [[]]],
|
|
||||||
["_activated", true, [true]]
|
|
||||||
];
|
|
||||||
|
|
||||||
if (isServer) exitWith {
|
|
||||||
private _instance_address = GETVAR(_logic,GVAR(instanceAddress),false);
|
|
||||||
private _instance_port = GETVAR(_logic,GVAR(instancePort),false);
|
|
||||||
private _instance_auth_user = GETVAR(_logic,GVAR(instanceAuthUser),false);
|
|
||||||
private _instance_auth_pass = GETVAR(_logic,GVAR(instanceAuthPassword),false);
|
|
||||||
|
|
||||||
SETMVAR(GVAR(instanceAddress),_instance_address);
|
|
||||||
SETMVAR(GVAR(instancePort),_instance_port);
|
|
||||||
SETMVAR(GVAR(instanceAuthUser),_instance_auth_user);
|
|
||||||
SETMVAR(GVAR(instanceAuthPassword),_instance_auth_pass);
|
|
||||||
|
|
||||||
_startAction = [
|
|
||||||
QGVAR(startStream),
|
|
||||||
"Start Video Feed",
|
|
||||||
"",
|
|
||||||
{
|
|
||||||
_uuid = (_this select 0) call armatak_fnc_extract_uuid;
|
|
||||||
_uuid_short = _uuid select [0, 8];
|
|
||||||
_role = roleDescription (_this select 0);
|
|
||||||
_name = name (_this select 0);
|
|
||||||
|
|
||||||
_role = [_role] call BIS_fnc_filterString;
|
|
||||||
_name = [_name] call BIS_fnc_filterString;
|
|
||||||
|
|
||||||
_stream_path = _name + "_" + _role + "_" + _uuid_short;
|
|
||||||
|
|
||||||
armatak_mediamtx_video_stream_instance_address = GETMVAR(instance_address,false);
|
|
||||||
armatak_mediamtx_video_stream_instance_port = missionNamespace getVariable "instance_port";
|
|
||||||
armatak_mediamtx_video_stream_instance_auth_user = missionNamespace getVariable "instance_auth_user";
|
|
||||||
armatak_mediamtx_video_stream_instance_auth_pass = missionNamespace getVariable "instance_auth_pass";
|
|
||||||
|
|
||||||
"armatak" callExtension ["video_stream:start", [armatak_mediamtx_video_stream_instance_address, armatak_mediamtx_video_stream_instance_port, _stream_path, armatak_mediamtx_video_stream_instance_auth_user, armatak_mediamtx_video_stream_instance_auth_pass]];
|
|
||||||
(_this select 0) setVariable ["armatak_video_feed_is_streaming", true];
|
|
||||||
},
|
|
||||||
{
|
|
||||||
(_this select 0) getVariable "armatak_video_feed_is_streaming" == false
|
|
||||||
}
|
|
||||||
] call ace_interact_menu_fnc_createAction;
|
|
||||||
[
|
|
||||||
"Man",
|
|
||||||
1,
|
|
||||||
["ACE_SelfActions"],
|
|
||||||
_startAction,
|
|
||||||
true
|
|
||||||
] call ace_interact_menu_fnc_addActionToClass;
|
|
||||||
|
|
||||||
_stopAction = [
|
|
||||||
"ArmatakStopStream",
|
|
||||||
"Stop Video Feed",
|
|
||||||
"",
|
|
||||||
{
|
|
||||||
"armatak" callExtension ["video_stream:stop", []];
|
|
||||||
SETVAR(_this select 0,GVAR(isStreaming),false);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
GETVAR((this select 0),GVAR(isStreaming),false)
|
|
||||||
}
|
|
||||||
] call ace_interact_menu_fnc_createAction;
|
|
||||||
[
|
|
||||||
"Man",
|
|
||||||
1,
|
|
||||||
["ACE_SelfActions"],
|
|
||||||
_stopAction,
|
|
||||||
true
|
|
||||||
] call ace_interact_menu_fnc_addActionToClass;
|
|
||||||
if (isMultiplayer) then {
|
|
||||||
{
|
|
||||||
SETVAR(_x,GVAR(isStreaming),false);
|
|
||||||
} forEach playableUnits;
|
|
||||||
} else {
|
|
||||||
SETVAR(player,GVAR(isStreaming),false);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
true;
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#define COMPONENT video
|
|
||||||
#define COMPONENT_BEAUTIFIED Video Streaming
|
|
||||||
#include "\armatak\armatak\addons\main\script_mod.hpp"
|
|
||||||
|
|
||||||
// #define DEBUG_MODE_FULL
|
|
||||||
// #define DISABLE_COMPILE_CACHE
|
|
||||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED_MAIN
|
|
||||||
#define DEBUG_MODE_FULL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG_SETTINGS_MAIN
|
|
||||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_MAIN
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "\z\ace\addons\main\script_macros.hpp"
|
|
||||||
1
app/.gitignore
vendored
1
app/.gitignore
vendored
@@ -1 +0,0 @@
|
|||||||
/build
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
plugins {
|
|
||||||
alias(libs.plugins.android.application)
|
|
||||||
alias(libs.plugins.jetbrains.kotlin.android)
|
|
||||||
}
|
|
||||||
|
|
||||||
android {
|
|
||||||
namespace = "com.armatak.simtak"
|
|
||||||
compileSdk = 34
|
|
||||||
|
|
||||||
defaultConfig {
|
|
||||||
applicationId = "com.armatak.simtak"
|
|
||||||
minSdk = 29
|
|
||||||
targetSdk = 34
|
|
||||||
versionCode = 1
|
|
||||||
versionName = "1.0"
|
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
|
||||||
}
|
|
||||||
|
|
||||||
buildTypes {
|
|
||||||
release {
|
|
||||||
isMinifyEnabled = false
|
|
||||||
proguardFiles(
|
|
||||||
getDefaultProguardFile("proguard-android-optimize.txt"),
|
|
||||||
"proguard-rules.pro"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
compileOptions {
|
|
||||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
targetCompatibility = JavaVersion.VERSION_1_8
|
|
||||||
}
|
|
||||||
kotlinOptions {
|
|
||||||
jvmTarget = "1.8"
|
|
||||||
}
|
|
||||||
viewBinding {
|
|
||||||
enable = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies {
|
|
||||||
|
|
||||||
implementation(libs.androidx.core.ktx)
|
|
||||||
implementation(libs.androidx.appcompat)
|
|
||||||
implementation(libs.material)
|
|
||||||
implementation(libs.androidx.activity)
|
|
||||||
implementation(libs.androidx.constraintlayout)
|
|
||||||
|
|
||||||
implementation(libs.okhttp)
|
|
||||||
//Vision - Qr/BarCodeScanner
|
|
||||||
implementation(libs.play.services.vision)
|
|
||||||
testImplementation(libs.junit)
|
|
||||||
androidTestImplementation(libs.androidx.junit)
|
|
||||||
androidTestImplementation(libs.androidx.espresso.core)
|
|
||||||
}
|
|
||||||
21
app/proguard-rules.pro
vendored
21
app/proguard-rules.pro
vendored
@@ -1,21 +0,0 @@
|
|||||||
# Add project specific ProGuard rules here.
|
|
||||||
# You can control the set of applied configuration files using the
|
|
||||||
# proguardFiles setting in build.gradle.
|
|
||||||
#
|
|
||||||
# For more details, see
|
|
||||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
|
||||||
|
|
||||||
# If your project uses WebView with JS, uncomment the following
|
|
||||||
# and specify the fully qualified class name to the JavaScript interface
|
|
||||||
# class:
|
|
||||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
|
||||||
# public *;
|
|
||||||
#}
|
|
||||||
|
|
||||||
# Uncomment this to preserve the line number information for
|
|
||||||
# debugging stack traces.
|
|
||||||
#-keepattributes SourceFile,LineNumberTable
|
|
||||||
|
|
||||||
# If you keep the line number information, uncomment this to
|
|
||||||
# hide the original source file name.
|
|
||||||
#-renamesourcefileattribute SourceFile
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.armatak.simtak
|
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
|
||||||
|
|
||||||
import org.junit.Test
|
|
||||||
import org.junit.runner.RunWith
|
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* See [testing documentation](http://d.android.com/tools/testing).
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
|
||||||
class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
fun useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
|
||||||
assertEquals("com.armatak.simtak", appContext.packageName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"
|
|
||||||
tools:ignore="ProtectedPermissions" />
|
|
||||||
</manifest>
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
|
||||||
|
|
||||||
<uses-feature
|
|
||||||
android:name="android.hardware.camera"
|
|
||||||
android:required="true" />
|
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus"
|
|
||||||
android:required="false"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
|
||||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
|
|
||||||
|
|
||||||
|
|
||||||
<application
|
|
||||||
android:allowBackup="true"
|
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
|
||||||
android:icon="@drawable/appicon_simtak"
|
|
||||||
android:usesCleartextTraffic="true"
|
|
||||||
android:label="@string/app_name"
|
|
||||||
android:roundIcon="@drawable/appicon_simtak"
|
|
||||||
android:supportsRtl="true"
|
|
||||||
android:theme="@style/Theme.SIMTAK"
|
|
||||||
tools:targetApi="31">
|
|
||||||
<activity
|
|
||||||
android:name=".trackerLog.TrackerLogActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:exported="false"
|
|
||||||
tools:ignore="LockedOrientationActivity" />
|
|
||||||
<activity
|
|
||||||
android:name=".ScannerActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
android:exported="false"
|
|
||||||
tools:ignore="LockedOrientationActivity" />
|
|
||||||
<activity
|
|
||||||
android:name=".HomeActivity"
|
|
||||||
android:screenOrientation="portrait"
|
|
||||||
tools:ignore="LockedOrientationActivity"
|
|
||||||
android:exported="true">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<service
|
|
||||||
android:name=".LocationSimulationService"
|
|
||||||
android:exported="true"
|
|
||||||
android:foregroundServiceType="location"
|
|
||||||
android:permission="android.permission.ACCESS_MOCK_LOCATION">
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</service>
|
|
||||||
</application>
|
|
||||||
|
|
||||||
</manifest>
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
package com.armatak.simtak
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.pm.PackageManager
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.net.Uri
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.provider.Settings
|
|
||||||
import android.view.Window
|
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import com.armatak.simtak.databinding.ActivityHomeBinding
|
|
||||||
import com.armatak.simtak.trackerLog.TrackerLogActivity
|
|
||||||
|
|
||||||
class HomeActivity : AppCompatActivity() {
|
|
||||||
private lateinit var binding: ActivityHomeBinding
|
|
||||||
private var requestCamera: ActivityResultLauncher<String>? = null
|
|
||||||
private var requestPermissionLauncher: ActivityResultLauncher<String>? = null
|
|
||||||
private var requested = false
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ActivityHomeBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
enableEdgeToEdge()
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
|
|
||||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
|
||||||
insets
|
|
||||||
}
|
|
||||||
|
|
||||||
requestCamera = registerForActivityResult(ActivityResultContracts.RequestPermission()) {
|
|
||||||
if (it) {
|
|
||||||
initScan()
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
this,
|
|
||||||
"Sem permissão para acessar a camera. Permita o acesso para continuar",
|
|
||||||
Toast.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestPermissionLauncher = registerForActivityResult(
|
|
||||||
ActivityResultContracts.RequestPermission(),
|
|
||||||
) { isGranted: Boolean ->
|
|
||||||
if (isGranted) {
|
|
||||||
Toast.makeText(baseContext, "Notificações Habilitadas", Toast.LENGTH_SHORT).show()
|
|
||||||
requestCamera?.launch(Manifest.permission.CAMERA)
|
|
||||||
} else {
|
|
||||||
Toast.makeText(
|
|
||||||
baseContext,
|
|
||||||
"Por favor confirme a permissão",
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
initUI()
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun validateUrl() {
|
|
||||||
val etServerAddressLayout = binding.etServerAddressLayout
|
|
||||||
val etServerAddress = binding.etServerAddress
|
|
||||||
val serverAddress = etServerAddress.text.toString()
|
|
||||||
|
|
||||||
val regexPatterns = listOf(
|
|
||||||
"^ws://\\b(?:(?:2(?:[0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9])\\.){3}(?:(?:2([0-4][0-9]|5[0-5])|[0-1]?[0-9]?[0-9]))\\b:[0-9]+\$",
|
|
||||||
"^ws://([A-Za-z0-9]+(\\.[A-Za-z0-9]+)+)\$"
|
|
||||||
)
|
|
||||||
|
|
||||||
val allowed = regexPatterns.any { patterns ->
|
|
||||||
Regex(patterns).matches(serverAddress)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(allowed) {
|
|
||||||
requested = false
|
|
||||||
val intent = Intent(this, TrackerLogActivity::class.java)
|
|
||||||
intent.putExtra("webSocketUrl", serverAddress)
|
|
||||||
startActivity(intent)
|
|
||||||
} else {
|
|
||||||
requested = false
|
|
||||||
etServerAddressLayout.error = "Server Address need to be a valid URL"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initScan() {
|
|
||||||
startActivity(Intent(this, ScannerActivity::class.java))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun initUI() {
|
|
||||||
binding.btnScanQrCode.setOnClickListener {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
|
||||||
if (ContextCompat.checkSelfPermission(
|
|
||||||
this,
|
|
||||||
Manifest.permission.POST_NOTIFICATIONS
|
|
||||||
) ==
|
|
||||||
PackageManager.PERMISSION_GRANTED
|
|
||||||
) {
|
|
||||||
requestCamera?.launch(Manifest.permission.CAMERA)
|
|
||||||
} else if (shouldShowRequestPermissionRationale(Manifest.permission.POST_NOTIFICATIONS)) {
|
|
||||||
requestNotificationByDialog()
|
|
||||||
} else {
|
|
||||||
requestPermissionLauncher?.launch(Manifest.permission.POST_NOTIFICATIONS)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.btnConnectToServer.setOnClickListener {
|
|
||||||
val serverAddress = binding.etServerAddress.text.toString()
|
|
||||||
if (!requested && serverAddress.isNotBlank()){
|
|
||||||
validateUrl()
|
|
||||||
} else {
|
|
||||||
binding.etServerAddressLayout.error = "This Input cannot be blank"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
configureFooterLinks()
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun requestNotificationByDialog() {
|
|
||||||
val dialog = Dialog(this)
|
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
||||||
dialog.setContentView(R.layout.dialog_alert)
|
|
||||||
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
|
|
||||||
val tvTitle: TextView = dialog.findViewById(R.id.title)
|
|
||||||
val tvMessage: TextView = dialog.findViewById(R.id.message)
|
|
||||||
val btnCancel: Button = dialog.findViewById(R.id.btnCancel)
|
|
||||||
val btnAccept: Button = dialog.findViewById(R.id.btnAccept)
|
|
||||||
|
|
||||||
btnCancel.text = getString(R.string.cancel)
|
|
||||||
btnCancel.setOnClickListener {
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
tvTitle.text = getString(R.string.allowNotificationsPermission)
|
|
||||||
tvMessage.text = getString(R.string.needNotificationsPermissionMessage)
|
|
||||||
btnAccept.text = getString(R.string.goToSettings)
|
|
||||||
btnAccept.setOnClickListener {
|
|
||||||
val intent = Intent(Settings.ACTION_APP_NOTIFICATION_SETTINGS)
|
|
||||||
intent.putExtra(Settings.EXTRA_APP_PACKAGE, this.packageName)
|
|
||||||
startActivity(intent)
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
dialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun configureFooterLinks() {
|
|
||||||
binding.btnGithubProject.setOnClickListener {
|
|
||||||
openLink(getString(R.string.githubProjectUrl))
|
|
||||||
}
|
|
||||||
binding.btnWiki.setOnClickListener {
|
|
||||||
openLink(getString(R.string.wikiUrl))
|
|
||||||
}
|
|
||||||
binding.btnDiscord.setOnClickListener {
|
|
||||||
openLink(getString(R.string.discordUrl))
|
|
||||||
}
|
|
||||||
binding.btnSteamProject.setOnClickListener {
|
|
||||||
openLink(getString(R.string.steamUrl))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun openLink(url: String) {
|
|
||||||
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
|
|
||||||
startActivity(intent)
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,237 +0,0 @@
|
|||||||
package com.armatak.simtak
|
|
||||||
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.app.Service
|
|
||||||
import android.content.Intent
|
|
||||||
import android.location.Location
|
|
||||||
import android.location.LocationManager
|
|
||||||
import android.location.provider.ProviderProperties
|
|
||||||
import android.os.Binder
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.IBinder
|
|
||||||
import android.os.Looper
|
|
||||||
import android.os.SystemClock
|
|
||||||
import android.util.Log
|
|
||||||
import com.armatak.simtak.core.Util.createNotificationChannel
|
|
||||||
import com.armatak.simtak.core.Util.getActualTime
|
|
||||||
import com.armatak.simtak.core.Util.getMockLocationStoppedNotification
|
|
||||||
import com.armatak.simtak.core.Util.getNeedReconnectNotification
|
|
||||||
import com.armatak.simtak.core.Util.getRunningNotification
|
|
||||||
import com.armatak.simtak.core.Util.getServiceDestroyedNotification
|
|
||||||
import com.armatak.simtak.core.Util.getStartedServiceNotification
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.ConnectionStatus
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.LogModel
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.LogTypes
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.flow.MutableStateFlow
|
|
||||||
import kotlinx.coroutines.flow.StateFlow
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import org.json.JSONObject
|
|
||||||
|
|
||||||
private const val TAG = "LocationSimulationService"
|
|
||||||
|
|
||||||
class LocationSimulationService : Service() {
|
|
||||||
private val binder = LocationMockBinder()
|
|
||||||
private lateinit var webSocketClient: WebSocketClient
|
|
||||||
|
|
||||||
private var logTrackerMutableList = mutableListOf<LogModel>()
|
|
||||||
private var lastLineId = 0
|
|
||||||
|
|
||||||
private var connectionAttemps = 0
|
|
||||||
|
|
||||||
private val _connectionStatus = MutableStateFlow<ConnectionStatus>(ConnectionStatus.InitialValue)
|
|
||||||
private val connectionStatus : StateFlow<ConnectionStatus> = _connectionStatus
|
|
||||||
private val _logTracker = MutableStateFlow(emptyList<LogModel>())
|
|
||||||
private val logTracker : StateFlow<List<LogModel>> = _logTracker
|
|
||||||
|
|
||||||
init {
|
|
||||||
Log.d(TAG, "$TAG, initialized")
|
|
||||||
}
|
|
||||||
|
|
||||||
private val socketListener = object : WebSocketClient.SocketListener {
|
|
||||||
override fun onMessage(message: String) {
|
|
||||||
try {
|
|
||||||
if (message[0] == '{') {
|
|
||||||
val jsonObject = JSONObject(message)
|
|
||||||
val latitude = jsonObject.getDouble("latitude")
|
|
||||||
val longitude = jsonObject.getDouble("longitude")
|
|
||||||
val bearing = jsonObject.getDouble("bearing")
|
|
||||||
simulateLocation(latitude, longitude, bearing)
|
|
||||||
addEntryToLog(message, LogTypes.Normal)
|
|
||||||
} else {
|
|
||||||
Log.e(TAG, "Non an JsonObject, text: $message")
|
|
||||||
addEntryToLog("Non an JsonObject, text: $message", LogTypes.Warning)
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, e.localizedMessage, e)
|
|
||||||
addEntryToLog(e.localizedMessage, LogTypes.Error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addEntryToLog(message: String?, type: LogTypes) {
|
|
||||||
lastLineId += 1
|
|
||||||
logTrackerMutableList.add(
|
|
||||||
LogModel(
|
|
||||||
lastLineId,
|
|
||||||
getActualTime(),
|
|
||||||
message?:"null",
|
|
||||||
type
|
|
||||||
)
|
|
||||||
)
|
|
||||||
val newList = logTrackerMutableList.toList()
|
|
||||||
_logTracker.value = newList
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getLog(): StateFlow<List<LogModel>> {
|
|
||||||
return logTracker
|
|
||||||
}
|
|
||||||
fun getConnectionStatus(): StateFlow<ConnectionStatus> {
|
|
||||||
return connectionStatus
|
|
||||||
}
|
|
||||||
|
|
||||||
fun connectToServer(url: String){
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
connectionAttemps ++
|
|
||||||
webSocketClient = WebSocketClient.getInstance()
|
|
||||||
addEntryToLog("Server Address: $url", LogTypes.NetworkOperation)
|
|
||||||
webSocketClient.setSocketUrl(url)
|
|
||||||
webSocketClient.setListener(socketListener)
|
|
||||||
webSocketClient.connect()
|
|
||||||
_connectionStatus.value = ConnectionStatus.Connected
|
|
||||||
addEntryToLog("Connection Server Success", LogTypes.NetworkOperation)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
Log.e(TAG, e.localizedMessage, e)
|
|
||||||
when (e.localizedMessage){
|
|
||||||
"Expected URL scheme 'http' or 'https' but no scheme was found for test u..." -> {
|
|
||||||
addEntryToLog("Expected ws:// or wss:// scheme, this is only for debug", LogTypes.Warning)
|
|
||||||
_connectionStatus.value = ConnectionStatus.Disconnected
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
if (connectionAttemps < 6){
|
|
||||||
addEntryToLog("Attemp: $connectionAttemps \nError:${e.localizedMessage}", LogTypes.Warning)
|
|
||||||
_connectionStatus.value = ConnectionStatus.OnReconnect
|
|
||||||
Handler(Looper.getMainLooper()).postDelayed({
|
|
||||||
connectToServer(url)
|
|
||||||
}, 1500)
|
|
||||||
} else {
|
|
||||||
addEntryToLog("Exceed Connection Attemps", LogTypes.Error)
|
|
||||||
connectionAttemps = -1
|
|
||||||
_connectionStatus.value = ConnectionStatus.Awaiting
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBind(intent: Intent): IBinder {
|
|
||||||
return binder
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun simulateLocation(latitude: Double, longitude: Double, bearing: Double) {
|
|
||||||
val locationManager = baseContext.getSystemService(LOCATION_SERVICE) as LocationManager
|
|
||||||
// Create a Location Object
|
|
||||||
val location = Location(LocationManager.GPS_PROVIDER)
|
|
||||||
location.latitude = latitude
|
|
||||||
location.longitude = longitude
|
|
||||||
location.accuracy = 3f
|
|
||||||
location.altitude = 0.0
|
|
||||||
location.time = System.currentTimeMillis()
|
|
||||||
location.bearing = bearing.toFloat()
|
|
||||||
location.setBearingAccuracyDegrees(0.1F)
|
|
||||||
location.setVerticalAccuracyMeters(0.1F)
|
|
||||||
location.setSpeedAccuracyMetersPerSecond(0.01F)
|
|
||||||
location.elapsedRealtimeNanos = SystemClock.elapsedRealtimeNanos()
|
|
||||||
var powerUsage = 3
|
|
||||||
var accuracy = 5
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S){
|
|
||||||
powerUsage = ProviderProperties.POWER_USAGE_LOW
|
|
||||||
accuracy = ProviderProperties.ACCURACY_COARSE
|
|
||||||
}
|
|
||||||
//Create Test Provider
|
|
||||||
locationManager.addTestProvider(
|
|
||||||
LocationManager.GPS_PROVIDER,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
powerUsage,
|
|
||||||
accuracy
|
|
||||||
)
|
|
||||||
// Enable Mock Provider
|
|
||||||
locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true)
|
|
||||||
|
|
||||||
// Mock Location on System
|
|
||||||
locationManager.setTestProviderLocation(LocationManager.GPS_PROVIDER, location)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun stopByActivity() {
|
|
||||||
webSocketClient.disconnect()
|
|
||||||
_connectionStatus.value = ConnectionStatus.Disconnected
|
|
||||||
addEntryToLog("Connection Stopped", LogTypes.NetworkOperation)
|
|
||||||
val locationManager = baseContext.getSystemService(LOCATION_SERVICE) as LocationManager
|
|
||||||
locationManager.removeTestProvider(LocationManager.GPS_PROVIDER)
|
|
||||||
addEntryToLog("MockLocation Stopped", LogTypes.Warning)
|
|
||||||
this.stopSelf()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate() {
|
|
||||||
super.onCreate()
|
|
||||||
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
createNotificationChannel(manager)
|
|
||||||
CoroutineScope(Dispatchers.Default).launch{
|
|
||||||
notifyStatusByPushNotification()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
|
||||||
val notification = getStartedServiceNotification(this)
|
|
||||||
startForeground(5142, notification)
|
|
||||||
return START_STICKY
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun notifyStatusByPushNotification(){
|
|
||||||
getConnectionStatus().collectLatest { status ->
|
|
||||||
when(status){
|
|
||||||
ConnectionStatus.Awaiting -> {
|
|
||||||
val notification = getNeedReconnectNotification(this)
|
|
||||||
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
manager.notify(5142, notification)
|
|
||||||
}
|
|
||||||
ConnectionStatus.Connected -> {
|
|
||||||
val notification = getRunningNotification(this)
|
|
||||||
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
manager.notify(5142, notification)
|
|
||||||
}
|
|
||||||
ConnectionStatus.Disconnected -> {
|
|
||||||
val notification = getMockLocationStoppedNotification(this)
|
|
||||||
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
manager.notify(5142, notification)
|
|
||||||
}
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
val notification = getServiceDestroyedNotification(this)
|
|
||||||
val manager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
|
|
||||||
manager.notify(5142, notification)
|
|
||||||
Log.e(TAG, "Service destroyed")
|
|
||||||
}
|
|
||||||
|
|
||||||
inner class LocationMockBinder: Binder(){
|
|
||||||
fun getService() = this@LocationSimulationService
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,114 +0,0 @@
|
|||||||
package com.armatak.simtak
|
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
|
||||||
import android.content.Intent
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.Handler
|
|
||||||
import android.os.Looper
|
|
||||||
import android.view.SurfaceHolder
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import com.armatak.simtak.databinding.ActivityScannerBinding
|
|
||||||
import com.armatak.simtak.trackerLog.TrackerLogActivity
|
|
||||||
import com.google.android.gms.vision.CameraSource
|
|
||||||
import com.google.android.gms.vision.Detector
|
|
||||||
import com.google.android.gms.vision.barcode.Barcode
|
|
||||||
import com.google.android.gms.vision.barcode.BarcodeDetector
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.withContext
|
|
||||||
import java.io.IOException
|
|
||||||
|
|
||||||
class ScannerActivity : AppCompatActivity() {
|
|
||||||
|
|
||||||
private lateinit var binding: ActivityScannerBinding
|
|
||||||
|
|
||||||
private var tentativa = false
|
|
||||||
private lateinit var barcodeDetector: BarcodeDetector
|
|
||||||
private lateinit var cameraSource: CameraSource
|
|
||||||
var intentData = ""
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ActivityScannerBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
initScanBarcode()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initScanBarcode() {
|
|
||||||
barcodeDetector = BarcodeDetector.Builder(this)
|
|
||||||
.setBarcodeFormats(Barcode.QR_CODE)
|
|
||||||
.build()
|
|
||||||
cameraSource = CameraSource.Builder(this, barcodeDetector)
|
|
||||||
.setRequestedPreviewSize(1080, 1080)
|
|
||||||
.setAutoFocusEnabled(true)
|
|
||||||
.setFacing(CameraSource.CAMERA_FACING_BACK)
|
|
||||||
.build()
|
|
||||||
binding.surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
|
|
||||||
@SuppressLint("MissingPermission")
|
|
||||||
override fun surfaceCreated(holder: SurfaceHolder) {
|
|
||||||
try {
|
|
||||||
cameraSource.start(binding.surfaceView.holder)
|
|
||||||
} catch (e: IOException) {
|
|
||||||
e.printStackTrace()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun surfaceChanged(
|
|
||||||
holder: SurfaceHolder,
|
|
||||||
format: Int,
|
|
||||||
width: Int,
|
|
||||||
height: Int
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun surfaceDestroyed(holder: SurfaceHolder) {
|
|
||||||
cameraSource.stop()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
barcodeDetector.setProcessor(object : Detector.Processor<Barcode> {
|
|
||||||
override fun release() {
|
|
||||||
Toast.makeText(applicationContext, "Scanner was stopped", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun receiveDetections(detections: Detector.Detections<Barcode>) {
|
|
||||||
val barcodes = detections.detectedItems
|
|
||||||
if (barcodes.size() != 0) {
|
|
||||||
Thread.sleep(300)
|
|
||||||
|
|
||||||
intentData = barcodes.valueAt(0).displayValue
|
|
||||||
|
|
||||||
|
|
||||||
if (!tentativa) {
|
|
||||||
initTrackerActivity(intentData)
|
|
||||||
tentativa = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initTrackerActivity(url: String?) {
|
|
||||||
lifecycleScope.launch(Dispatchers.IO) {
|
|
||||||
if (url != null) {
|
|
||||||
val intent = Intent(this@ScannerActivity, TrackerLogActivity::class.java)
|
|
||||||
intent.putExtra("webSocketUrl", url)
|
|
||||||
startActivity(intent)
|
|
||||||
Handler(Looper.getMainLooper()).postDelayed(
|
|
||||||
{ tentativa = false },
|
|
||||||
2000
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
Toast.makeText(baseContext, "Try Again, Scan Error", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
Handler(Looper.getMainLooper()).postDelayed(
|
|
||||||
{ tentativa = false },
|
|
||||||
1500
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,121 +0,0 @@
|
|||||||
package com.armatak.simtak
|
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import okhttp3.OkHttpClient
|
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import okhttp3.WebSocketListener
|
|
||||||
|
|
||||||
class WebSocketClient {
|
|
||||||
private lateinit var webSocket: okhttp3.WebSocket
|
|
||||||
private var socketListener: SocketListener? = null
|
|
||||||
private var socketUrl = ""
|
|
||||||
private var shouldReconnect = true
|
|
||||||
private var client: OkHttpClient? = null
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private lateinit var instance: WebSocketClient
|
|
||||||
|
|
||||||
@JvmStatic
|
|
||||||
@Synchronized
|
|
||||||
//This function gives singleton instance of WebSocket.
|
|
||||||
fun getInstance(): WebSocketClient {
|
|
||||||
synchronized(WebSocketClient::class) {
|
|
||||||
if (!::instance.isInitialized) {
|
|
||||||
instance = WebSocketClient()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return instance
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setListener(listener: SocketListener) {
|
|
||||||
this.socketListener = listener
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setSocketUrl(socketUrl: String) {
|
|
||||||
this.socketUrl = socketUrl
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initWebSocket() {
|
|
||||||
Log.e("socketCheck", "initWebSocket() socketurl = $socketUrl")
|
|
||||||
client = OkHttpClient()
|
|
||||||
val request = Request.Builder().url(url = socketUrl).build()
|
|
||||||
webSocket = client!!.newWebSocket(request, webSocketListener)
|
|
||||||
//this must me done else memory leak will be caused
|
|
||||||
client!!.dispatcher.executorService.shutdown()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun connect() {
|
|
||||||
Log.e("socketCheck", "connect()")
|
|
||||||
shouldReconnect = true
|
|
||||||
initWebSocket()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun reconnect() {
|
|
||||||
Log.e("socketCheck", "reconnect()")
|
|
||||||
initWebSocket()
|
|
||||||
}
|
|
||||||
|
|
||||||
//send
|
|
||||||
|
|
||||||
@Suppress("unused")
|
|
||||||
fun sendMessage(message: String) {
|
|
||||||
Log.e("socketCheck", "sendMessage($message)")
|
|
||||||
if (::webSocket.isInitialized) webSocket.send(message)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//We can close socket by two way:
|
|
||||||
|
|
||||||
//1. websocket.webSocket.close(1000, "Dont need connection")
|
|
||||||
//This attempts to initiate a graceful shutdown of this web socket.
|
|
||||||
//Any already-enqueued messages will be transmitted before the close message is sent but
|
|
||||||
//subsequent calls to send will return false and their messages will not be enqueued.
|
|
||||||
|
|
||||||
//2. websocket.cancel()
|
|
||||||
//This immediately and violently release resources held by this web socket,
|
|
||||||
//discarding any enqueued messages.
|
|
||||||
|
|
||||||
//Both does nothing if the web socket has already been closed or canceled.
|
|
||||||
fun disconnect() {
|
|
||||||
if (::webSocket.isInitialized) webSocket.close(1000, "Do not need connection anymore.")
|
|
||||||
shouldReconnect = false
|
|
||||||
}
|
|
||||||
|
|
||||||
interface SocketListener {
|
|
||||||
fun onMessage(message: String)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private val webSocketListener = object : WebSocketListener() {
|
|
||||||
//called when connection succeeded
|
|
||||||
//we are sending a message just after the socket is opened
|
|
||||||
override fun onOpen(webSocket: okhttp3.WebSocket, response: Response) {
|
|
||||||
Log.e("socketCheck", "onOpen()")
|
|
||||||
}
|
|
||||||
|
|
||||||
//called when text message received
|
|
||||||
override fun onMessage(webSocket: okhttp3.WebSocket, text: String) {
|
|
||||||
socketListener?.onMessage(text)
|
|
||||||
}
|
|
||||||
|
|
||||||
//called when binary message received
|
|
||||||
override fun onClosing(webSocket: okhttp3.WebSocket, code: Int, reason: String) {
|
|
||||||
Log.e("socketCheck", "onClosing()")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onClosed(webSocket: okhttp3.WebSocket, code: Int, reason: String) {
|
|
||||||
//called when no more messages and the connection should be released
|
|
||||||
Log.e("socketCheck", "onClosed()")
|
|
||||||
if (shouldReconnect) reconnect()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onFailure(
|
|
||||||
webSocket: okhttp3.WebSocket, t: Throwable, response: Response?
|
|
||||||
) {
|
|
||||||
Log.e("socketCheck", "onFailure()")
|
|
||||||
if (shouldReconnect) reconnect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
package com.armatak.simtak.core
|
|
||||||
|
|
||||||
import android.app.Notification
|
|
||||||
import android.app.NotificationChannel
|
|
||||||
import android.app.NotificationManager
|
|
||||||
import android.content.Context
|
|
||||||
import androidx.core.app.NotificationCompat
|
|
||||||
import com.armatak.simtak.R
|
|
||||||
import java.time.LocalDateTime
|
|
||||||
import java.time.format.DateTimeFormatter
|
|
||||||
|
|
||||||
object Util {
|
|
||||||
const val CHANNEL_ID = "websocketChannel"
|
|
||||||
fun getActualTime(): String {
|
|
||||||
val now = LocalDateTime.now()
|
|
||||||
val formatter = DateTimeFormatter.ofPattern("HH:mm:ss:SSS")
|
|
||||||
return now.format(formatter)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createNotificationChannel(manager: NotificationManager) {
|
|
||||||
val websocketChannel = NotificationChannel(
|
|
||||||
CHANNEL_ID, "websocketChannelName",
|
|
||||||
NotificationManager.IMPORTANCE_HIGH
|
|
||||||
)
|
|
||||||
websocketChannel.description = "websocketChannelDescription"
|
|
||||||
websocketChannel.enableVibration(true)
|
|
||||||
manager.createNotificationChannel(websocketChannel)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getStartedServiceNotification(context: Context): Notification {
|
|
||||||
return NotificationCompat.Builder(context, CHANNEL_ID)
|
|
||||||
.setContentTitle("Service Started")
|
|
||||||
.setContentText("Service is ready to Start Tracking")
|
|
||||||
.setSmallIcon(R.drawable.appicon_simtak)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
fun getRunningNotification(context: Context): Notification {
|
|
||||||
return NotificationCompat.Builder(context, CHANNEL_ID)
|
|
||||||
.setContentTitle("Mocking Location")
|
|
||||||
.setContentText("Service is running")
|
|
||||||
.setSmallIcon(R.drawable.appicon_simtak)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun getNeedReconnectNotification(context: Context): Notification{
|
|
||||||
return NotificationCompat.Builder(context, CHANNEL_ID)
|
|
||||||
.setContentTitle("Need restart server connection")
|
|
||||||
.setContentText("Connection attempts failed. Check your network/server and try again")
|
|
||||||
.setSmallIcon(R.drawable.appicon_simtak)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
fun getMockLocationStoppedNotification(context: Context): Notification{
|
|
||||||
return NotificationCompat.Builder(context, CHANNEL_ID)
|
|
||||||
.setContentTitle("Mock Location Stopped")
|
|
||||||
.setContentText("Disconnect from server")
|
|
||||||
.setSmallIcon(R.drawable.appicon_simtak)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
fun getServiceDestroyedNotification(context: Context): Notification{
|
|
||||||
return NotificationCompat.Builder(context, CHANNEL_ID)
|
|
||||||
.setContentTitle("Service Destroyed")
|
|
||||||
.setSmallIcon(R.drawable.appicon_simtak)
|
|
||||||
.build()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
package com.armatak.simtak.trackerLog
|
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.Dialog
|
|
||||||
import android.content.ComponentName
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
|
||||||
import android.content.ServiceConnection
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.os.IBinder
|
|
||||||
import android.view.Window
|
|
||||||
import android.widget.Button
|
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
|
||||||
import com.armatak.simtak.LocationSimulationService
|
|
||||||
import com.armatak.simtak.R
|
|
||||||
import com.armatak.simtak.databinding.ActivityTrackerLogBinding
|
|
||||||
import com.armatak.simtak.trackerLog.data.adapters.AdapterLogTracker
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.ConnectionStatus
|
|
||||||
import kotlinx.coroutines.flow.collectLatest
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
class TrackerLogActivity : AppCompatActivity() {
|
|
||||||
private var connectedToServer: Boolean = false
|
|
||||||
private lateinit var binding: ActivityTrackerLogBinding
|
|
||||||
private var url: String = ""
|
|
||||||
private lateinit var locationPermissionRequest : ActivityResultLauncher<Array<String>>
|
|
||||||
|
|
||||||
private var serviceStarted = false
|
|
||||||
|
|
||||||
private var rvAdapter = AdapterLogTracker()
|
|
||||||
private var lastThreeElementsAreVisible = false
|
|
||||||
|
|
||||||
private lateinit var mService: LocationSimulationService
|
|
||||||
private var mBound = false
|
|
||||||
private val mConnection = object : ServiceConnection{
|
|
||||||
override fun onServiceConnected(className: ComponentName?, binder : IBinder?) {
|
|
||||||
val service = binder as LocationSimulationService.LocationMockBinder
|
|
||||||
mService = service.getService()
|
|
||||||
mBound = true
|
|
||||||
initCollectors()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onServiceDisconnected(name: ComponentName?) {
|
|
||||||
mBound = false
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initCollectors() {
|
|
||||||
lifecycleScope.launch {
|
|
||||||
if (mBound){
|
|
||||||
mService.getLog().collect { logModelList ->
|
|
||||||
rvAdapter.submitList(logModelList)
|
|
||||||
if (lastThreeElementsAreVisible){
|
|
||||||
binding.rvLogTracker.smoothScrollToPosition(rvAdapter.itemCount - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lifecycleScope.launch {
|
|
||||||
if (mBound){
|
|
||||||
mService.getConnectionStatus().collectLatest {
|
|
||||||
when (it){
|
|
||||||
ConnectionStatus.Connected -> {
|
|
||||||
binding.txtServerConnectionStatus.text = getString(R.string.serverConnectionStatusPropertyFormat, "Connected")
|
|
||||||
}
|
|
||||||
ConnectionStatus.Disconnected -> {
|
|
||||||
binding.txtServerConnectionStatus.text = getString(R.string.serverConnectionStatusPropertyFormat, "Disconnected")
|
|
||||||
}
|
|
||||||
ConnectionStatus.OnReconnect -> {
|
|
||||||
binding.txtServerConnectionStatus.text = getString(R.string.serverConnectionStatusPropertyFormat, "OnReconnect")
|
|
||||||
}
|
|
||||||
ConnectionStatus.Awaiting -> {
|
|
||||||
binding.txtServerConnectionStatus.text = getString(R.string.serverConnectionStatusPropertyFormat, "Awaiting")
|
|
||||||
showConnectionErrorDialog()
|
|
||||||
}
|
|
||||||
ConnectionStatus.InitialValue -> {
|
|
||||||
binding.txtServerConnectionStatus.text = getString(R.string.serverConnectionStatusPropertyFormat, "Not Initialized")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun showConnectionErrorDialog() {
|
|
||||||
val dialog = Dialog(this)
|
|
||||||
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE)
|
|
||||||
dialog.setContentView(R.layout.dialog_alert)
|
|
||||||
dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
|
|
||||||
|
|
||||||
val tvTitle: TextView = dialog.findViewById(R.id.title)
|
|
||||||
val tvMessage: TextView = dialog.findViewById(R.id.message)
|
|
||||||
val btnCancel: Button = dialog.findViewById(R.id.btnCancel)
|
|
||||||
val btnAccept: Button = dialog.findViewById(R.id.btnAccept)
|
|
||||||
|
|
||||||
btnCancel.text = getString(R.string.cancel)
|
|
||||||
btnCancel.setOnClickListener {
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
tvTitle.text = getString(R.string.serverConnectionProblems)
|
|
||||||
tvMessage.text = getString(R.string.errorDescriptionFormat, "Connection attempts failed. Check your network/server and try again")
|
|
||||||
btnAccept.text = getString(R.string.tryAgain)
|
|
||||||
btnAccept.setOnClickListener {
|
|
||||||
if(mBound) mService.connectToServer(url)
|
|
||||||
dialog.dismiss()
|
|
||||||
}
|
|
||||||
dialog.show()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
|
||||||
super.onCreate(savedInstanceState)
|
|
||||||
binding = ActivityTrackerLogBinding.inflate(layoutInflater)
|
|
||||||
setContentView(binding.root)
|
|
||||||
enableEdgeToEdge()
|
|
||||||
ViewCompat.setOnApplyWindowInsetsListener(binding.root) { v, insets ->
|
|
||||||
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
|
|
||||||
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
|
|
||||||
insets
|
|
||||||
}
|
|
||||||
|
|
||||||
url = intent.getStringExtra("webSocketUrl") ?: ""
|
|
||||||
|
|
||||||
locationPermissionRequest = registerForActivityResult(
|
|
||||||
ActivityResultContracts.RequestMultiplePermissions()
|
|
||||||
) { permissions ->
|
|
||||||
when {
|
|
||||||
permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
|
|
||||||
if(!serviceStarted){
|
|
||||||
Intent(this, LocationSimulationService::class.java).also {
|
|
||||||
startService(it)
|
|
||||||
bindService(it, mConnection, Context.BIND_AUTO_CREATE)
|
|
||||||
}
|
|
||||||
serviceStarted = true
|
|
||||||
}
|
|
||||||
if(mBound && !connectedToServer){
|
|
||||||
mService.connectToServer(url)
|
|
||||||
connectedToServer = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
|
|
||||||
if(!serviceStarted){
|
|
||||||
Intent(this, LocationSimulationService::class.java).also {
|
|
||||||
startService(it)
|
|
||||||
bindService(it, mConnection, Context.BIND_AUTO_CREATE)
|
|
||||||
}
|
|
||||||
serviceStarted = true
|
|
||||||
}
|
|
||||||
if(mBound && !connectedToServer){
|
|
||||||
mService.connectToServer(url)
|
|
||||||
connectedToServer = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Toast.makeText(baseContext, "Problems with permission", Toast.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onStart() {
|
|
||||||
super.onStart()
|
|
||||||
initUI()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun initUI() {
|
|
||||||
|
|
||||||
binding.txtServerAddress.text = getString(R.string.serverAddressPropertyFormat, url)
|
|
||||||
|
|
||||||
binding.btnBack.setOnClickListener {
|
|
||||||
if (!connectedToServer){
|
|
||||||
onBackPressedDispatcher.onBackPressed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.startService.setOnClickListener {
|
|
||||||
val connectionStatus = if (mBound){
|
|
||||||
mService.getConnectionStatus().value
|
|
||||||
} else {
|
|
||||||
ConnectionStatus.InitialValue
|
|
||||||
}
|
|
||||||
when (connectionStatus){
|
|
||||||
ConnectionStatus.Awaiting -> requestLocationPermission()
|
|
||||||
ConnectionStatus.InitialValue -> requestLocationPermission()
|
|
||||||
ConnectionStatus.Disconnected -> requestLocationPermission()
|
|
||||||
else -> {
|
|
||||||
Toast.makeText(this, "SIMTAK Service is already running", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!serviceStarted){
|
|
||||||
binding.startService.performClick()
|
|
||||||
}
|
|
||||||
binding.stopService.setOnClickListener {
|
|
||||||
val connectionStatus = if (mBound){
|
|
||||||
mService.getConnectionStatus().value
|
|
||||||
} else {
|
|
||||||
ConnectionStatus.InitialValue
|
|
||||||
}
|
|
||||||
when (connectionStatus){
|
|
||||||
ConnectionStatus.Awaiting -> secureStopService()
|
|
||||||
ConnectionStatus.Connected -> secureStopService()
|
|
||||||
ConnectionStatus.OnReconnect -> secureStopService()
|
|
||||||
else -> {
|
|
||||||
Toast.makeText(this, "SIMTAK Service is already stopped", Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setUpLogTrackerRV()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setUpLogTrackerRV() {
|
|
||||||
val rv = binding.rvLogTracker
|
|
||||||
rv.adapter = rvAdapter
|
|
||||||
rv.layoutManager = LinearLayoutManager(this)
|
|
||||||
rv.addOnScrollListener(object : RecyclerView.OnScrollListener(){
|
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
|
||||||
val layoutManager = recyclerView.layoutManager as LinearLayoutManager?
|
|
||||||
layoutManager?.let {
|
|
||||||
val totalItemCount = it.itemCount
|
|
||||||
val lastVisibleItemPosition = it.findLastVisibleItemPosition()
|
|
||||||
|
|
||||||
lastThreeElementsAreVisible = totalItemCount - lastVisibleItemPosition <= 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun secureStopService(){
|
|
||||||
if (mBound){
|
|
||||||
mService.stopByActivity()
|
|
||||||
connectedToServer = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onResume() {
|
|
||||||
super.onResume()
|
|
||||||
if (rvAdapter.itemCount -1 > 0){
|
|
||||||
binding.rvLogTracker.smoothScrollToPosition(rvAdapter.itemCount - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun requestLocationPermission() {
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
|
|
||||||
locationPermissionRequest.launch(
|
|
||||||
arrayOf(
|
|
||||||
Manifest.permission.FOREGROUND_SERVICE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
super.onDestroy()
|
|
||||||
mService.stopByActivity()
|
|
||||||
unbindService(mConnection)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
package com.armatak.simtak.trackerLog.data.adapters
|
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.recyclerview.widget.DiffUtil
|
|
||||||
import androidx.recyclerview.widget.ListAdapter
|
|
||||||
import com.armatak.simtak.R
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.LogModel
|
|
||||||
import com.armatak.simtak.trackerLog.data.viewHolder.ViewHolderLogTracker
|
|
||||||
|
|
||||||
class AdapterLogTracker: ListAdapter<LogModel, ViewHolderLogTracker>(DIFF_CALLBACK) {
|
|
||||||
companion object{
|
|
||||||
private val DIFF_CALLBACK = object : DiffUtil.ItemCallback<LogModel>(){
|
|
||||||
override fun areItemsTheSame(oldItem: LogModel, newItem: LogModel): Boolean {
|
|
||||||
return oldItem.idLine == newItem.idLine
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun areContentsTheSame(oldItem: LogModel, newItem: LogModel): Boolean {
|
|
||||||
return oldItem == newItem
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolderLogTracker {
|
|
||||||
val layoutInflater = LayoutInflater.from(parent.context)
|
|
||||||
return ViewHolderLogTracker(
|
|
||||||
layoutInflater.inflate(
|
|
||||||
R.layout.item_log_tracker,
|
|
||||||
parent,
|
|
||||||
false
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: ViewHolderLogTracker, position: Int) {
|
|
||||||
val item = getItem(position)
|
|
||||||
holder.render(item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
package com.armatak.simtak.trackerLog.data.models
|
|
||||||
|
|
||||||
sealed interface ConnectionStatus {
|
|
||||||
data object Connected : ConnectionStatus
|
|
||||||
data object Disconnected : ConnectionStatus
|
|
||||||
data object OnReconnect : ConnectionStatus
|
|
||||||
data object Awaiting : ConnectionStatus
|
|
||||||
data object InitialValue : ConnectionStatus
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
package com.armatak.simtak.trackerLog.data.models
|
|
||||||
|
|
||||||
data class LogModel(
|
|
||||||
val idLine: Int,
|
|
||||||
val time: String,
|
|
||||||
val body: String,
|
|
||||||
val type: LogTypes
|
|
||||||
)
|
|
||||||
|
|
||||||
sealed interface LogTypes {
|
|
||||||
data object Error : LogTypes
|
|
||||||
data object Warning : LogTypes
|
|
||||||
data object Normal : LogTypes
|
|
||||||
data object NetworkOperation : LogTypes
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
package com.armatak.simtak.trackerLog.data.viewHolder
|
|
||||||
|
|
||||||
import android.view.View
|
|
||||||
import androidx.recyclerview.widget.RecyclerView.ViewHolder
|
|
||||||
import com.armatak.simtak.R
|
|
||||||
import com.armatak.simtak.databinding.ItemLogTrackerBinding
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.LogModel
|
|
||||||
import com.armatak.simtak.trackerLog.data.models.LogTypes
|
|
||||||
|
|
||||||
class ViewHolderLogTracker(view: View) : ViewHolder(view) {
|
|
||||||
private val binding = ItemLogTrackerBinding.bind(view)
|
|
||||||
|
|
||||||
fun render(item: LogModel) {
|
|
||||||
val tvLogBody = binding.tvLogBody
|
|
||||||
val tvLogType = binding.tvLogType
|
|
||||||
binding.tvLogTime.text = item.time
|
|
||||||
tvLogBody.text = item.body
|
|
||||||
|
|
||||||
tvLogType.apply {
|
|
||||||
when (item.type) {
|
|
||||||
LogTypes.Error -> {
|
|
||||||
tvLogBody.setTextColor(context.getColor(R.color.errorColor))
|
|
||||||
setTextColor(context.getColor(R.color.errorColor))
|
|
||||||
text = context.getString(R.string.error)
|
|
||||||
}
|
|
||||||
|
|
||||||
LogTypes.NetworkOperation -> {
|
|
||||||
tvLogBody.setTextColor(context.getColor(R.color.networkColor))
|
|
||||||
setTextColor(context.getColor(R.color.networkColor))
|
|
||||||
text = context.getString(R.string.networkOperation)
|
|
||||||
}
|
|
||||||
LogTypes.Normal -> {
|
|
||||||
tvLogBody.setTextColor(context.getColor(R.color.darkGrey))
|
|
||||||
setTextColor(context.getColor(R.color.darkGrey))
|
|
||||||
text = context.getString(R.string.normal)
|
|
||||||
}
|
|
||||||
LogTypes.Warning -> {
|
|
||||||
tvLogBody.setTextColor(context.getColor(R.color.warningColor))
|
|
||||||
setTextColor(context.getColor(R.color.warningColor))
|
|
||||||
text = context.getString(R.string.warning)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
<vector android:height="500dp" android:viewportHeight="1000"
|
|
||||||
android:viewportWidth="1000" android:width="500dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:pathData="M731.7,11.3H831A157.7,157.7 0,0 1,988.7 169v99.3"
|
|
||||||
android:strokeColor="#fff" android:strokeLineCap="round"
|
|
||||||
android:strokeLineJoin="round" android:strokeWidth="22"/>
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:pathData="M988.7,731.7V831A157.7,157.7 0,0 1,831 988.7H731.7"
|
|
||||||
android:strokeColor="#fff" android:strokeLineCap="round"
|
|
||||||
android:strokeLineJoin="round" android:strokeWidth="22"/>
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:pathData="M268.3,11.3H169A157.7,157.7 0,0 0,11.3 169v99.3"
|
|
||||||
android:strokeColor="#fff" android:strokeLineCap="round"
|
|
||||||
android:strokeLineJoin="round" android:strokeWidth="22"/>
|
|
||||||
<path android:fillColor="#00000000"
|
|
||||||
android:pathData="M11.3,731.7V831A157.7,157.7 0,0 0,169 988.7h99.3"
|
|
||||||
android:strokeColor="#fff" android:strokeLineCap="round"
|
|
||||||
android:strokeLineJoin="round" android:strokeWidth="22"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:width="680.31dp"
|
|
||||||
android:height="680.31dp"
|
|
||||||
android:viewportWidth="680.31"
|
|
||||||
android:viewportHeight="680.31">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M92.18,340.15C76.15,278.43 66.36,217 66.03,153.9c8.93,-1.43 17.25,-2.64 25.52,-4.12c28.79,-5.15 55.83,-15.34 82.3,-27.6c33.51,-15.52 64.93,-34.45 94.7,-56.17c13.83,-10.09 27.44,-20.47 40.98,-30.94c8.11,-6.27 16.01,-12.83 23.75,-19.55c2.87,-2.49 4.5,-1.53 6.93,0.47c14.98,12.33 29.8,24.89 45.23,36.64c30.57,23.27 62.65,44.42 96.97,61.65c37.67,18.91 76.63,34.75 119.31,38.42c5.37,0.46 5.35,3.53 5.29,7.49c-0.66,42.46 -5.59,84.46 -13.93,126.06c-3.53,17.65 -7.63,35.19 -11.71,53.89c4.81,0 9.53,0.34 14.18,-0.08c6.02,-0.55 9.09,1.5 10.64,7.65c2.9,11.51 6.58,22.83 10.07,34.19c14.6,47.51 29.26,95 43.86,142.51c2.54,8.26 1.44,9.7 -7.23,9.71c-53.57,0.02 -107.13,0.08 -160.7,-0.11c-4.9,-0.02 -7.76,1.59 -10.74,5.4c-10.3,13.14 -20.27,26.68 -31.85,38.65c-27.19,28.11 -56.81,53.49 -89.62,74.97c-2.27,1.49 -4.82,2.55 -7.15,3.95c-20.68,12.4 -11.96,12.53 -33.08,-0.3c-32.98,-20.03 -62.8,-44.05 -89.1,-72.24c-13.67,-14.65 -26.52,-30.09 -39.33,-45.5c-2.98,-3.58 -5.78,-4.91 -10.29,-4.9c-53.11,0.14 -106.22,0.09 -159.33,0.09c-10.49,0 -11.18,-0.97 -8.17,-11.05c12.55,-42.04 24.96,-84.11 37.68,-126.09c5.27,-17.39 11.03,-34.65 17.05,-51.79c0.78,-2.21 4.33,-4.47 6.86,-4.81C80.52,339.64 86.07,340.15 92.18,340.15zM337.35,48.77c-23.64,17.52 -46.73,34.97 -70.17,51.93c-30.67,22.18 -63.72,40.19 -98.84,54.29c-23.84,9.58 -48.61,15.72 -75.45,18.38c2.69,56.69 11.2,112.1 25.9,166.46c2.04,0.11 2.94,0.2 3.85,0.2c141.92,0.01 283.83,-0.02 425.75,0.11c4.61,0 6.42,-1.57 7.32,-5.87c4.37,-20.81 9.38,-41.5 13.34,-62.39c2.77,-14.59 4.48,-29.4 6.22,-44.16c2.11,-18 3.76,-36.06 5.46,-52.67c-19.58,-4.51 -37.32,-7.87 -54.65,-12.73c-30.79,-8.63 -59.22,-23.05 -86.22,-39.75c-23.86,-14.75 -46.55,-31.42 -69.41,-47.73C358.77,66.51 347.87,57.1 337.35,48.77zM454.8,534.62c-79.39,0 -156.77,0 -234.15,0c-0.65,0.78 -1.29,1.56 -1.94,2.34c3.85,3.03 7.98,5.76 11.51,9.13c15.51,14.79 30,30.81 46.49,44.39c17.75,14.61 37.28,27.09 56.22,40.22c1.65,1.15 5.3,1.16 7.09,0.12c27.7,-16.2 53.45,-35.12 76.65,-57.29C429.35,561.41 441.26,548.49 454.8,534.62zM497.06,493.41"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
<path
|
|
||||||
android:pathData="M337.35,48.77c10.51,8.33 21.42,17.73 33.08,26.06c22.86,16.31 45.56,32.97 69.41,47.73c27.01,16.7 55.43,31.12 86.22,39.75c17.32,4.86 35.06,8.23 54.65,12.73c-1.7,16.61 -3.34,34.67 -5.46,52.67c-1.73,14.76 -3.45,29.57 -6.22,44.16c-3.97,20.89 -8.97,41.58 -13.34,62.39c-0.9,4.3 -2.71,5.87 -7.32,5.87c-141.92,-0.13 -283.83,-0.1 -425.75,-0.11c-0.9,0 -1.8,-0.09 -3.85,-0.2c-14.7,-54.36 -23.21,-109.76 -25.9,-166.46c26.84,-2.66 51.61,-8.8 75.45,-18.38c35.12,-14.1 68.17,-32.11 98.84,-54.29C290.63,83.75 313.72,66.29 337.35,48.77zM446.57,175.27c-0.65,0.6 -1.3,1.2 -1.95,1.8c0.35,1.84 0.1,4.33 1.2,5.35c1.1,1.02 4.11,1.35 5.27,0.54c1.04,-0.74 1.57,-3.92 0.84,-5.17c-3.67,-6.29 -7.99,-12.19 -11.76,-18.42c-12.65,-20.93 -30.07,-33.52 -55.54,-31.79c-16.32,1.11 -30.75,7.69 -44.08,16.75c-2.86,1.94 -4.63,2.3 -7.76,0.48c-7.81,-4.55 -15.72,-9.09 -24.04,-12.54c-24,-9.97 -49.16,-5.07 -65.28,12.91c-5.41,6.04 -9.3,13.45 -13.82,20.28c-2.43,3.67 -4.85,7.37 -6.99,11.21c-0.95,1.7 -1.2,3.79 -1.76,5.7c1.63,0.45 3.81,1.75 4.75,1.14c1.45,-0.94 2.22,-3.13 2.95,-4.92c0.5,-1.23 -0.02,-3.5 0.72,-3.93c11.14,-6.5 22.09,-13.47 33.78,-18.79c6.01,-2.74 13.36,-0.26 17.07,5.5c6.03,9.37 10.8,19.54 16.11,29.37c-3.63,0.36 -5.71,-0.68 -7.87,-0.92c-10.77,-1.19 -21.56,-2.15 -32.34,-3.22c-2.94,-0.29 -5.86,-0.93 -8.79,-0.93c-1.57,0 -3.42,0.7 -4.6,1.71c-0.57,0.49 -0.37,3.12 0.3,3.57c1.28,0.86 3.99,1.69 4.61,1.06c4.23,-4.34 8.12,-1.62 11.73,0.43c10.94,6.23 20.32,14.15 25.42,24.28c-15.25,10.24 -30.1,20.2 -44.93,30.18c-7.18,4.83 -11.6,13.51 -21.22,15.04c-0.92,0.15 -2.24,2.59 -2.03,3.71c0.23,1.21 1.97,2.86 3.17,2.97c1.16,0.1 2.64,-1.36 3.66,-2.44c1.5,-1.58 2.42,-4.56 4.09,-4.98c13.67,-3.42 27.38,-6.85 41.25,-9.32c9.19,-1.63 18.67,-1.69 29.36,-2.55c-11.44,20.96 -16.58,41.85 -20.49,63.17c-0.43,2.37 -3.12,4.34 -4.8,6.47c-1.01,1.28 -2.08,2.5 -3.12,3.74c1.59,1.09 3.18,3.04 4.75,3.01c1.26,-0.02 2.74,-2.27 3.65,-3.81c1.38,-2.32 1.78,-5.48 3.6,-7.25c15.41,-14.92 31.09,-29.56 46.57,-44.4c2.89,-2.77 5.27,-6.06 7.16,-8.27c15.93,15.32 31.53,30.34 47.17,45.31c2.31,2.21 4.79,4.25 7.22,6.34c2.68,2.31 6.17,3.98 4.98,8.74c-0.21,0.86 2.23,3.42 3.24,3.31c1.72,-0.18 3.28,-1.86 4.91,-2.91c-1.06,-1.23 -2.19,-2.4 -3.17,-3.69c-1.73,-2.27 -3.89,-4.4 -4.9,-6.98c-1.23,-3.14 -1.19,-6.75 -2.15,-10.02c-5.1,-17.35 -10.34,-34.66 -15.52,-51.98c0.58,-0.03 2.36,-0.19 4.14,-0.17c20.72,0.26 40.7,4.87 60.5,10.45c3.22,0.91 7.64,0.09 7.45,5.78c-0.03,0.81 2.62,2.15 4.16,2.39c0.77,0.12 2.71,-1.87 2.58,-2.65c-0.25,-1.53 -1.26,-3.36 -2.53,-4.21c-1.93,-1.3 -4.69,-1.43 -6.51,-2.82c-11.03,-8.45 -21.52,-17.65 -32.92,-25.55c-8.52,-5.91 -18.14,-10.23 -27.21,-15.23c6.11,-11.76 15.6,-19.73 26.74,-25.87c3.42,-1.89 7.11,-4.6 11.11,-0.32c0.65,0.7 3.51,0.15 4.67,-0.72c0.77,-0.58 0.98,-3.44 0.3,-4.07c-1.07,-1 -3.08,-1.35 -4.69,-1.33c-2.94,0.02 -5.87,0.72 -8.81,0.75c-4.75,0.06 -9.58,-0.78 -14.24,-0.19c-7.79,1 -15.48,2.84 -25.23,4.71c5.26,-10.08 9.38,-19.11 14.52,-27.5c4.76,-7.77 14.31,-11.22 24.69,-5.91C426.4,163.01 436.37,169.35 446.57,175.27z"
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
<path
|
|
||||||
android:pathData="M454.8,534.62c-13.54,13.87 -25.45,26.79 -38.13,38.91c-23.2,22.18 -48.95,41.09 -76.65,57.29c-1.79,1.05 -5.43,1.03 -7.09,-0.12c-18.94,-13.13 -38.47,-25.61 -56.22,-40.22c-16.5,-13.58 -30.98,-29.6 -46.49,-44.39c-3.53,-3.37 -7.66,-6.1 -11.51,-9.13c0.65,-0.78 1.29,-1.56 1.94,-2.34C298.03,534.62 375.41,534.62 454.8,534.62z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M446.57,175.27c-10.19,-5.91 -20.16,-12.26 -30.64,-17.62c-10.39,-5.31 -19.93,-1.86 -24.69,5.91c-5.14,8.4 -9.26,17.42 -14.52,27.5c9.75,-1.87 17.43,-3.71 25.23,-4.71c4.66,-0.6 9.49,0.24 14.24,0.19c2.94,-0.03 5.87,-0.73 8.81,-0.75c1.61,-0.01 3.63,0.33 4.69,1.33c0.67,0.63 0.47,3.49 -0.3,4.07c-1.16,0.87 -4.02,1.42 -4.67,0.72c-4,-4.28 -7.69,-1.57 -11.11,0.32c-11.14,6.14 -20.63,14.11 -26.74,25.87c9.07,5 18.69,9.33 27.21,15.23c11.4,7.9 21.89,17.09 32.92,25.55c1.82,1.39 4.58,1.53 6.51,2.82c1.27,0.85 2.28,2.68 2.53,4.21c0.13,0.79 -1.81,2.77 -2.58,2.65c-1.54,-0.23 -4.19,-1.57 -4.16,-2.39c0.19,-5.69 -4.23,-4.87 -7.45,-5.78c-19.81,-5.58 -39.78,-10.19 -60.5,-10.45c-1.78,-0.02 -3.57,0.14 -4.14,0.17c5.19,17.32 10.43,34.63 15.52,51.98c0.96,3.27 0.92,6.88 2.15,10.02c1.01,2.57 3.17,4.71 4.9,6.98c0.98,1.29 2.11,2.47 3.17,3.69c-1.63,1.05 -3.19,2.73 -4.91,2.91c-1.02,0.11 -3.46,-2.45 -3.24,-3.31c1.19,-4.76 -2.3,-6.43 -4.98,-8.74c-2.43,-2.09 -4.91,-4.13 -7.22,-6.34c-15.64,-14.98 -31.24,-30 -47.17,-45.31c-1.89,2.21 -4.27,5.5 -7.16,8.27c-15.49,14.84 -31.17,29.48 -46.57,44.4c-1.82,1.76 -2.22,4.93 -3.6,7.25c-0.92,1.54 -2.4,3.79 -3.65,3.81c-1.57,0.03 -3.17,-1.92 -4.75,-3.01c1.04,-1.25 2.12,-2.47 3.12,-3.74c1.68,-2.13 4.36,-4.1 4.8,-6.47c3.91,-21.32 9.05,-42.22 20.49,-63.17c-10.69,0.87 -20.16,0.92 -29.36,2.55c-13.87,2.47 -27.57,5.9 -41.25,9.32c-1.66,0.42 -2.59,3.4 -4.09,4.98c-1.02,1.08 -2.5,2.54 -3.66,2.44c-1.2,-0.1 -2.94,-1.76 -3.17,-2.97c-0.21,-1.12 1.11,-3.56 2.03,-3.71c9.62,-1.53 14.05,-10.21 21.22,-15.04c14.83,-9.98 29.68,-19.94 44.93,-30.18c-5.09,-10.13 -14.48,-18.05 -25.42,-24.28c-3.6,-2.05 -7.49,-4.77 -11.73,-0.43c-0.61,0.63 -3.33,-0.2 -4.61,-1.06c-0.67,-0.45 -0.87,-3.08 -0.3,-3.57c1.18,-1.01 3.03,-1.71 4.6,-1.71c2.93,0 5.86,0.64 8.79,0.93c10.78,1.07 21.58,2.03 32.34,3.22c2.17,0.24 4.24,1.28 7.87,0.92c-5.31,-9.83 -10.08,-20 -16.11,-29.37c-3.71,-5.76 -11.06,-8.24 -17.07,-5.5c-11.69,5.33 -22.64,12.3 -33.78,18.79c-0.74,0.43 -0.22,2.7 -0.72,3.93c-0.73,1.79 -1.5,3.98 -2.95,4.92c-0.94,0.61 -3.12,-0.69 -4.75,-1.14c0.57,-1.91 0.82,-4 1.76,-5.7c2.14,-3.84 4.56,-7.54 6.99,-11.21c4.52,-6.83 8.41,-14.24 13.82,-20.28c16.12,-17.99 41.28,-22.88 65.28,-12.91c8.32,3.46 16.23,8 24.04,12.54c3.13,1.82 4.9,1.47 7.76,-0.48c13.33,-9.06 27.76,-15.64 44.08,-16.75c25.47,-1.74 42.89,10.86 55.54,31.79c3.77,6.23 8.1,12.13 11.76,18.42c0.72,1.24 0.2,4.43 -0.84,5.17c-1.15,0.81 -4.16,0.48 -5.27,-0.54c-1.11,-1.02 -0.86,-3.51 -1.2,-5.35C445.27,176.46 445.92,175.86 446.57,175.27zM311.8,199.86c4.96,1.46 9.92,2.93 15.7,4.63C325.69,193.56 320.47,191.78 311.8,199.86zM360.9,199.7c-0.23,-0.83 -0.45,-1.66 -0.68,-2.49c-8,-5.19 -12.73,-3.49 -14.83,7.19C351.17,202.65 356.03,201.17 360.9,199.7z"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
<path
|
|
||||||
android:pathData="M311.8,199.86c8.68,-8.08 13.9,-6.3 15.7,4.63C321.72,202.78 316.76,201.32 311.8,199.86z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M360.9,199.7c-4.87,1.48 -9.73,2.95 -15.51,4.71c2.1,-10.68 6.83,-12.39 14.83,-7.19C360.44,198.04 360.67,198.87 360.9,199.7z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M60.46,456.26l28.2,-1.85c0.61,4.81 1.85,8.47 3.73,10.99c3.05,4.08 7.42,6.11 13.09,6.11c4.23,0 7.49,-1.04 9.78,-3.13c2.29,-2.08 3.44,-4.5 3.44,-7.25c0,-2.61 -1.09,-4.95 -3.27,-7.01c-2.18,-2.06 -7.24,-4.01 -15.18,-5.84c-13,-3.07 -22.27,-7.15 -27.81,-12.23c-5.58,-5.08 -8.38,-11.56 -8.38,-19.44c0,-5.17 1.43,-10.06 4.29,-14.67c2.86,-4.6 7.15,-8.22 12.89,-10.86c5.74,-2.63 13.6,-3.95 23.59,-3.95c12.26,0 21.6,2.39 28.04,7.18c6.43,4.79 10.26,12.4 11.48,22.84l-27.94,1.72c-0.74,-4.53 -2.3,-7.83 -4.68,-9.89c-2.38,-2.06 -5.66,-3.09 -9.85,-3.09c-3.45,0 -6.04,0.77 -7.79,2.3c-1.75,1.54 -2.62,3.4 -2.62,5.6c0,1.6 0.72,3.05 2.16,4.33c1.4,1.33 4.71,2.57 9.95,3.71c12.96,2.93 22.23,5.9 27.84,8.9c5.6,3 9.68,6.72 12.24,11.16c2.55,4.44 3.83,9.41 3.83,14.91c0,6.46 -1.7,12.41 -5.1,17.86c-3.4,5.45 -8.16,9.58 -14.26,12.4c-6.11,2.82 -13.81,4.23 -23.1,4.23c-16.31,0 -27.61,-3.3 -33.89,-9.89C64.84,474.81 61.28,466.42 60.46,456.26z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M158.08,388.86h29.71v100.72h-29.71V388.86z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M203.23,388.86h38.98l15.03,61.28l14.93,-61.28h38.96v100.72h-24.27v-76.81l-18.7,76.81h-21.97l-18.67,-76.81v76.81h-24.27V388.86z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M317.8,388.86h90.1v24.87h-30.23v75.85h-29.64v-75.85H317.8V388.86z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M465.69,472.95h-33.65l-4.67,16.63H397.1l36.05,-100.72h32.33l36.04,100.72h-31.04L465.69,472.95zM459.54,451.17l-10.59,-36.21l-10.48,36.21H459.54z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
<path
|
|
||||||
android:pathData="M505.58,388.86h29.64v38.06l31.05,-38.06h39.42l-35,38.02l36.57,62.7h-36.5l-20.22,-41.42L535.22,465v24.58h-29.64V388.86z"
|
|
||||||
android:fillColor="#FFFFFF"/>
|
|
||||||
</vector>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:autoMirrored="true" android:height="60dp" android:tint="#6E3B23" android:viewportHeight="24" android:viewportWidth="24" android:width="60dp">
|
|
||||||
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
|
||||||
|
|
||||||
</vector>
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#FFFFFF" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp">
|
|
||||||
|
|
||||||
<path android:fillColor="@android:color/white" android:pathData="M16.01,7L16,3h-2v4h-4V3H8v4h-0.01C7,6.99 6,7.99 6,8.99v5.49L9.5,18v3h5v-3l3.5,-3.51v-5.5c0,-1 -1,-2 -1.99,-1.99z"/>
|
|
||||||
|
|
||||||
</vector>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:height="60dp" android:viewportHeight="32" android:viewportWidth="32" android:width="60dp">
|
|
||||||
|
|
||||||
<path android:fillColor="#000000" android:pathData="M20.992,20.163c-1.511,-0.099 -2.699,-1.349 -2.699,-2.877 0,-0.051 0.001,-0.102 0.004,-0.153l-0,0.007c-0.003,-0.048 -0.005,-0.104 -0.005,-0.161 0,-1.525 1.19,-2.771 2.692,-2.862l0.008,-0c1.509,0.082 2.701,1.325 2.701,2.847 0,0.062 -0.002,0.123 -0.006,0.184l0,-0.008c0.003,0.05 0.005,0.109 0.005,0.168 0,1.523 -1.191,2.768 -2.693,2.854l-0.008,0zM11.026,20.163c-1.511,-0.099 -2.699,-1.349 -2.699,-2.877 0,-0.051 0.001,-0.102 0.004,-0.153l-0,0.007c-0.003,-0.048 -0.005,-0.104 -0.005,-0.161 0,-1.525 1.19,-2.771 2.692,-2.862l0.008,-0c1.509,0.082 2.701,1.325 2.701,2.847 0,0.062 -0.002,0.123 -0.006,0.184l0,-0.008c0.003,0.048 0.005,0.104 0.005,0.161 0,1.525 -1.19,2.771 -2.692,2.862l-0.008,0zM26.393,6.465c-1.763,-0.832 -3.811,-1.49 -5.955,-1.871l-0.149,-0.022c-0.005,-0.001 -0.011,-0.002 -0.017,-0.002 -0.035,0 -0.065,0.019 -0.081,0.047l-0,0c-0.234,0.411 -0.488,0.924 -0.717,1.45l-0.043,0.111c-1.03,-0.165 -2.218,-0.259 -3.428,-0.259s-2.398,0.094 -3.557,0.275l0.129,-0.017c-0.27,-0.63 -0.528,-1.142 -0.813,-1.638l0.041,0.077c-0.017,-0.029 -0.048,-0.047 -0.083,-0.047 -0.005,0 -0.011,0 -0.016,0.001l0.001,-0c-2.293,0.403 -4.342,1.06 -6.256,1.957l0.151,-0.064c-0.017,0.007 -0.031,0.019 -0.04,0.034l-0,0c-2.854,4.041 -4.562,9.069 -4.562,14.496 0,0.907 0.048,1.802 0.141,2.684l-0.009,-0.11c0.003,0.029 0.018,0.053 0.039,0.07l0,0c2.14,1.601 4.628,2.891 7.313,3.738l0.176,0.048c0.008,0.003 0.018,0.004 0.028,0.004 0.032,0 0.06,-0.015 0.077,-0.038l0,-0c0.535,-0.72 1.044,-1.536 1.485,-2.392l0.047,-0.1c0.006,-0.012 0.01,-0.027 0.01,-0.043 0,-0.041 -0.026,-0.075 -0.062,-0.089l-0.001,-0c-0.912,-0.352 -1.683,-0.727 -2.417,-1.157l0.077,0.042c-0.029,-0.017 -0.048,-0.048 -0.048,-0.083 0,-0.031 0.015,-0.059 0.038,-0.076l0,-0c0.157,-0.118 0.315,-0.24 0.465,-0.364 0.016,-0.013 0.037,-0.021 0.059,-0.021 0.014,0 0.027,0.003 0.038,0.008l-0.001,-0c2.208,1.061 4.8,1.681 7.536,1.681s5.329,-0.62 7.643,-1.727l-0.107,0.046c0.012,-0.006 0.025,-0.009 0.04,-0.009 0.022,0 0.043,0.008 0.059,0.021l-0,-0c0.15,0.124 0.307,0.248 0.466,0.365 0.023,0.018 0.038,0.046 0.038,0.077 0,0.035 -0.019,0.065 -0.046,0.082l-0,0c-0.661,0.395 -1.432,0.769 -2.235,1.078l-0.105,0.036c-0.036,0.014 -0.062,0.049 -0.062,0.089 0,0.016 0.004,0.031 0.011,0.044l-0,-0.001c0.501,0.96 1.009,1.775 1.571,2.548l-0.04,-0.057c0.017,0.024 0.046,0.04 0.077,0.04 0.01,0 0.02,-0.002 0.029,-0.004l-0.001,0c2.865,-0.892 5.358,-2.182 7.566,-3.832l-0.065,0.047c0.022,-0.016 0.036,-0.041 0.039,-0.069l0,-0c0.087,-0.784 0.136,-1.694 0.136,-2.615 0,-5.415 -1.712,-10.43 -4.623,-14.534l0.052,0.078c-0.008,-0.016 -0.022,-0.029 -0.038,-0.036l-0,-0z"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
|
|
||||||
</vector>
|
|
||||||
@@ -1,22 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:height="60dp" android:viewportHeight="24" android:viewportWidth="24" android:width="60dp">
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:fillType="evenOdd" android:pathData="M12,0.296c-6.627,0 -12,5.372 -12,12c0,5.302 3.438,9.8 8.206,11.387c0.6,0.111 0.82,-0.26 0.82,-0.577c0,-0.286 -0.011,-1.231 -0.016,-2.234c-3.338,0.726 -4.043,-1.416 -4.043,-1.416C4.421,18.069 3.635,17.7 3.635,17.7c-1.089,-0.745 0.082,-0.729 0.082,-0.729c1.205,0.085 1.839,1.237 1.839,1.237c1.07,1.834 2.807,1.304 3.492,0.997C9.156,18.429 9.467,17.9 9.81,17.6c-2.665,-0.303 -5.467,-1.332 -5.467,-5.93c0,-1.31 0.469,-2.381 1.237,-3.221C5.455,8.146 5.044,6.926 5.696,5.273c0,0 1.008,-0.322 3.301,1.23C9.954,6.237 10.98,6.104 12,6.099c1.02,0.005 2.047,0.138 3.006,0.404c2.29,-1.553 3.297,-1.23 3.297,-1.23c0.653,1.653 0.242,2.873 0.118,3.176c0.769,0.84 1.235,1.911 1.235,3.221c0,4.609 -2.807,5.624 -5.479,5.921c0.43,0.372 0.814,1.103 0.814,2.222c0,1.606 -0.014,2.898 -0.014,3.293c0,0.319 0.216,0.694 0.824,0.576c4.766,-1.589 8.2,-6.085 8.2,-11.385C24,5.669 18.627,0.296 12,0.296z"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M4.545,17.526c-0.026,0.06 -0.12,0.078 -0.206,0.037c-0.087,-0.039 -0.136,-0.121 -0.108,-0.18c0.026,-0.061 0.12,-0.078 0.207,-0.037C4.525,17.384 4.575,17.466 4.545,17.526L4.545,17.526z"/>
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M5.031,18.068c-0.057,0.053 -0.169,0.028 -0.245,-0.055c-0.079,-0.084 -0.093,-0.196 -0.035,-0.249c0.059,-0.053 0.167,-0.028 0.246,0.056C5.076,17.903 5.091,18.014 5.031,18.068L5.031,18.068z"/>
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M5.504,18.759c-0.074,0.051 -0.194,0.003 -0.268,-0.103c-0.074,-0.107 -0.074,-0.235 0.002,-0.286c0.074,-0.051 0.193,-0.005 0.268,0.101C5.579,18.579 5.579,18.707 5.504,18.759L5.504,18.759z"/>
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M6.152,19.427c-0.066,0.073 -0.206,0.053 -0.308,-0.046c-0.105,-0.097 -0.134,-0.234 -0.068,-0.307c0.067,-0.073 0.208,-0.052 0.311,0.046C6.191,19.217 6.222,19.355 6.152,19.427L6.152,19.427z"/>
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M7.047,19.814c-0.029,0.094 -0.164,0.137 -0.3,0.097C6.611,19.87 6.522,19.76 6.55,19.665c0.028,-0.095 0.164,-0.139 0.301,-0.096C6.986,19.609 7.075,19.719 7.047,19.814L7.047,19.814z"/>
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M8.029,19.886c0.003,0.099 -0.112,0.181 -0.255,0.183c-0.143,0.003 -0.26,-0.077 -0.261,-0.174c0,-0.1 0.113,-0.181 0.256,-0.184C7.912,19.708 8.029,19.788 8.029,19.886L8.029,19.886z"/>
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="M8.943,19.731c0.017,0.096 -0.082,0.196 -0.224,0.222c-0.139,0.026 -0.268,-0.034 -0.286,-0.13c-0.017,-0.099 0.084,-0.198 0.223,-0.224C8.797,19.574 8.925,19.632 8.943,19.731L8.943,19.731z"/>
|
|
||||||
|
|
||||||
</vector>
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path
|
|
||||||
android:fillColor="#3DDC84"
|
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M9,0L9,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,0L19,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,0L29,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,0L39,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,0L49,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,0L59,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,0L69,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,0L79,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M89,0L89,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M99,0L99,108"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,9L108,9"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,19L108,19"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,29L108,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,39L108,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,49L108,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,59L108,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,69L108,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,79L108,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,89L108,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M0,99L108,99"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,29L89,29"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,39L89,39"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,49L89,49"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,59L89,59"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,69L89,69"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M19,79L89,79"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M29,19L29,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M39,19L39,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M49,19L49,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M59,19L59,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M69,19L69,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M79,19L79,89"
|
|
||||||
android:strokeWidth="0.8"
|
|
||||||
android:strokeColor="#33FFFFFF" />
|
|
||||||
</vector>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:aapt="http://schemas.android.com/aapt"
|
|
||||||
android:width="108dp"
|
|
||||||
android:height="108dp"
|
|
||||||
android:viewportWidth="108"
|
|
||||||
android:viewportHeight="108">
|
|
||||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
|
||||||
<aapt:attr name="android:fillColor">
|
|
||||||
<gradient
|
|
||||||
android:endX="85.84757"
|
|
||||||
android:endY="92.4963"
|
|
||||||
android:startX="42.9492"
|
|
||||||
android:startY="49.59793"
|
|
||||||
android:type="linear">
|
|
||||||
<item
|
|
||||||
android:color="#44000000"
|
|
||||||
android:offset="0.0" />
|
|
||||||
<item
|
|
||||||
android:color="#00000000"
|
|
||||||
android:offset="1.0" />
|
|
||||||
</gradient>
|
|
||||||
</aapt:attr>
|
|
||||||
</path>
|
|
||||||
<path
|
|
||||||
android:fillColor="#FFFFFF"
|
|
||||||
android:fillType="nonZero"
|
|
||||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
|
||||||
android:strokeWidth="1"
|
|
||||||
android:strokeColor="#00000000" />
|
|
||||||
</vector>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:height="30dp" android:viewportHeight="24" android:viewportWidth="24" android:width="30dp">
|
|
||||||
|
|
||||||
<path android:fillColor="#FF000000" android:pathData="m12.707,12.707l-2.293,2.293 -1.414,-1.414 2.293,-2.293c0.391,-0.391 0.391,-1.023 0,-1.414s-1.023,-0.391 -1.414,0l-2.293,2.293 -1.879,-1.879c-0.391,-0.391 -1.023,-0.391 -1.414,0s-0.391,1.023 0,1.414l0.352,0.352 -1.134,1.135c-1.77,1.769 -1.982,4.515 -0.638,6.519l-2.58,2.58c-0.391,0.391 -0.391,1.023 0,1.414 0.195,0.195 0.451,0.293 0.707,0.293s0.512,-0.098 0.707,-0.293l2.58,-2.58c0.865,0.58 1.868,0.871 2.871,0.871 1.321,0 2.642,-0.503 3.647,-1.509l1.135,-1.134 0.352,0.352c0.195,0.195 0.451,0.293 0.707,0.293s0.512,-0.098 0.707,-0.293c0.391,-0.391 0.391,-1.023 0,-1.414l-1.879,-1.879 2.293,-2.293c0.391,-0.391 0.391,-1.023 0,-1.414s-1.023,-0.391 -1.414,0ZM23.707,0.293c-0.391,-0.391 -1.023,-0.391 -1.414,0l-2.58,2.58c-2.004,-1.344 -4.749,-1.132 -6.519,0.638l-1.135,1.135 -0.353,-0.353c-0.391,-0.391 -1.023,-0.391 -1.414,0s-0.391,1.023 0,1.414l8,8c0.195,0.195 0.451,0.293 0.707,0.293s0.512,-0.098 0.707,-0.293c0.391,-0.391 0.391,-1.023 0,-1.414l-0.353,-0.353 1.135,-1.135c1.77,-1.769 1.982,-4.515 0.638,-6.519l2.58,-2.58c0.391,-0.391 0.391,-1.023 0,-1.414Z"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
|
|
||||||
</vector>
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:height="60dp" android:viewportHeight="32" android:viewportWidth="32" android:width="60dp">
|
|
||||||
|
|
||||||
<path android:fillColor="#000000" android:pathData="M18.102,12.129c0,-0 0,-0 0,-0.001 0,-1.564 1.268,-2.831 2.831,-2.831s2.831,1.268 2.831,2.831c0,1.564 -1.267,2.831 -2.831,2.831 -0,0 -0,0 -0.001,0h0c-0,0 -0,0 -0.001,0 -1.563,0 -2.83,-1.267 -2.83,-2.83 0,-0 0,-0 0,-0.001v0zM24.691,12.135c0,-2.081 -1.687,-3.768 -3.768,-3.768s-3.768,1.687 -3.768,3.768c0,2.081 1.687,3.768 3.768,3.768v0c2.08,-0.003 3.765,-1.688 3.768,-3.767v-0zM10.427,23.76l-1.841,-0.762c0.524,1.078 1.611,1.808 2.868,1.808 1.317,0 2.448,-0.801 2.93,-1.943l0.008,-0.021c0.155,-0.362 0.246,-0.784 0.246,-1.226 0,-1.757 -1.424,-3.181 -3.181,-3.181 -0.405,0 -0.792,0.076 -1.148,0.213l0.022,-0.007 1.903,0.787c0.852,0.364 1.439,1.196 1.439,2.164 0,1.296 -1.051,2.347 -2.347,2.347 -0.324,0 -0.632,-0.066 -0.913,-0.184l0.015,0.006zM15.974,1.004c-7.857,0.001 -14.301,6.046 -14.938,13.738l-0.004,0.054 8.038,3.322c0.668,-0.462 1.495,-0.737 2.387,-0.737 0.001,0 0.002,0 0.002,0h-0c0.079,0 0.156,0.005 0.235,0.008l3.575,-5.176v-0.074c0.003,-3.12 2.533,-5.648 5.653,-5.648 3.122,0 5.653,2.531 5.653,5.653s-2.531,5.653 -5.653,5.653h-0.131l-5.094,3.638c0,0.065 0.005,0.131 0.005,0.199 0,0.001 0,0.002 0,0.003 0,2.342 -1.899,4.241 -4.241,4.241 -2.047,0 -3.756,-1.451 -4.153,-3.38l-0.005,-0.027 -5.755,-2.383c1.841,6.345 7.601,10.905 14.425,10.905 8.281,0 14.994,-6.713 14.994,-14.994s-6.713,-14.994 -14.994,-14.994c-0,0 -0.001,0 -0.001,0h0z"
|
|
||||||
tools:ignore="VectorPath" />
|
|
||||||
|
|
||||||
</vector>
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:width="200dp"
|
|
||||||
android:height="200dp"
|
|
||||||
android:viewportWidth="24"
|
|
||||||
android:viewportHeight="24">
|
|
||||||
<path
|
|
||||||
android:fillColor="#FF000000"
|
|
||||||
android:pathData="M22.922,1.7a2.985,2.985 0,0 0,-2.458 -0.648l-6.18,1.123A3.993,3.993 0,0 0,12 3.461,3.993 3.993,0 0,0 9.716,2.172L3.536,1.049A3,3 0,0 0,0 4L0,20.834l12,2.183 12,-2.183L24,4A2.992,2.992 0,0 0,22.922 1.7ZM11,20.8 L2,19.166L2,4a1,1 0,0 1,1.179 -0.983L9.358,4.14A2,2 0,0 1,11 6.108ZM22,19.164L13,20.8L13,6.108A2,2 0,0 1,14.642 4.14l6.179,-1.123A1,1 0,0 1,22 4Z"/>
|
|
||||||
</vector>
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user