Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
7f08e4c
Add files via upload
efekrbas Mar 21, 2026
7b498a9
Update metadata.json
efekrbas Mar 21, 2026
9916b1d
Handle empty slug case in extractPageTitle function
efekrbas Mar 21, 2026
10ea68e
Update presence.ts
efekrbas Mar 21, 2026
2b5ee86
Update presence.ts
efekrbas Mar 21, 2026
9bf1fa8
Fix formatting issue in metadata.json
efekrbas Mar 21, 2026
43daea3
Update presence.ts
efekrbas Mar 21, 2026
f6c4919
Update presence.ts
efekrbas Mar 21, 2026
c4e8c9d
Update metadata.json
efekrbas Mar 21, 2026
e057b05
Update presence.ts
efekrbas Mar 21, 2026
e286237
Update metadata.json
efekrbas Mar 21, 2026
09589b0
Update metadata.json
efekrbas Mar 21, 2026
66c2f03
Update metadata.json
efekrbas Mar 21, 2026
e3022a1
Refactor extractPageTitle and getPageData functions
efekrbas Mar 21, 2026
ec41f2c
Delete websites/H/Hackviser/bg.jpg
efekrbas Mar 21, 2026
4c096f8
Add files via upload
efekrbas Mar 21, 2026
a74f427
Merge branch 'main' into main
efekrbas Mar 22, 2026
5bf3e14
Update presence.ts
efekrbas Mar 23, 2026
8d5922a
Delete websites/H/Hackviser/bg.jpg
efekrbas Mar 23, 2026
5724b39
Update metadata.json
efekrbas Mar 23, 2026
8fdbeb6
Update presence.ts
efekrbas Mar 23, 2026
a00c784
Update presence.ts
efekrbas Mar 23, 2026
cf8b55a
Refactor presence data structure and comments
efekrbas Mar 23, 2026
49781b3
Fix logo and thumbnail URLs in metadata.json
efekrbas Mar 23, 2026
750bc98
Update metadata.json
efekrbas Mar 23, 2026
20e780f
Delete websites/H/Hackviser/icon.png
efekrbas Mar 23, 2026
7a62efb
Merge branch 'main' into main
efekrbas Mar 23, 2026
1648036
Merge branch 'main' into main
efekrbas Mar 25, 2026
ddd6d1b
Merge branch 'main' into main
efekrbas Mar 26, 2026
a252a37
Merge branch 'main' into main
efekrbas Mar 26, 2026
355a0e1
Update websites/H/Hackviser/metadata.json
efekrbas Mar 27, 2026
364a809
Update metadata.json
efekrbas Mar 27, 2026
5f3011f
Update presence.ts
efekrbas Mar 27, 2026
cf82ac3
Update presence.ts
efekrbas Mar 27, 2026
3dd8b59
Update metadata.json
efekrbas Mar 27, 2026
035aa54
Update presence.ts
efekrbas Mar 27, 2026
eb7ee2e
Update presence.ts
efekrbas Mar 27, 2026
307959c
Change presenceData type to PresenceData
efekrbas Apr 1, 2026
23c56e4
Merge branch 'main' into main
efekrbas Apr 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions websites/H/Hackviser/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"$schema": "https://schemas.premid.app/metadata/1.16",
"apiVersion": 1,
"author": {
"id": "378501743366897675",
"name": "hackviser"
},
"service": "Hackviser",
"description": {
"en": "Hackviser is an online cybersecurity training platform where you can practice hacking skills through labs, CTF challenges, learning paths, and real-world scenarios.",
"tr": "Hackviser, laboratuvarlar, CTF yarışmaları, öğrenme yolları ve gerçek dünya senaryoları aracılığıyla siber güvenlik becerilerinizi geliştirebileceğiniz çevrimiçi bir eğitim platformudur."
},
"url": "hackviser.com",
"regExp": "^https?[:][/][/]([a-zA-Z0-9-]+[.])*hackviser[.]com[/]",
"version": "1.0.0",
"logo": "https://i.ibb.co/ns57qq7g/512x512.jpg",
"thumbnail": "https://github.com/user-attachments/assets/bf3d8382-4789-494e-802a-244f571bf676?v=.png",
"color": "#00ff00",
"category": "other",
"tags": [
"cybersecurity",
"hacking",
"ctf",
"labs",
"learning"
]
}
292 changes: 292 additions & 0 deletions websites/H/Hackviser/presence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
const presence = new Presence({
clientId: '1476565376513999030',
})

let startTimestamp = Math.floor(Date.now() / 1000)
let lastPage = ''

/**
* Converts a URL slug into a human-readable title.
*/
function extractPageTitle(pathname: string): string | null {
const parts = pathname.split('/').filter(p => p.length > 0)
if (parts.length >= 2) {
const slug = parts[parts.length - 1] || ''
return slug
.replace(/[-_]/g, ' ')
.replace(/\b\w/g, l => l.toUpperCase())
}
return null
}

/**
* Determines page info from the current pathname.
*/
function getPageData(pathname: string): {
page: string
details: string
state: string
sensitive: boolean
} {
// ── Auth pages (sensitive) ──────────────────────────────────
if (
pathname.startsWith('/login')
|| pathname.startsWith('/register')
|| pathname.startsWith('/forgot')
|| pathname.startsWith('/reset')
) {
return {
page: 'login',
details: 'Logging In',
state: '',
sensitive: true,
}
}

// ── Home ────────────────────────────────────────────────────
if (pathname.startsWith('/home') || pathname === '/') {
return {
page: 'home',
details: 'Home Page',
state: 'Viewing Home Page',
sensitive: false,
}
}

// ── Dashboard ───────────────────────────────────────────────
if (pathname.startsWith('/dashboard')) {
return {
page: 'dashboard',
details: 'Dashboard',
state: 'Viewing Stats',
sensitive: false,
}
}

// ── Academy ─────────────────────────────────────────────────
if (pathname.startsWith('/academy')) {
const subPage = extractPageTitle(pathname)
return {
page: 'academy',
details: 'Academy',
state: subPage || 'Browsing Categories',
sensitive: false,
}
}

// ── Warmups ─────────────────────────────────────────────────
if (
pathname.startsWith('/warmups')
|| pathname.startsWith('/warmup')
) {
const name = extractPageTitle(pathname)
return {
page: 'warmups',
details: 'Warmups',
state: name || 'Warming Up...',
sensitive: false,
}
}

// ── Scenarios ───────────────────────────────────────────────
if (
pathname.startsWith('/scenarios')
|| pathname.startsWith('/scenario')
) {
const name = extractPageTitle(pathname)
return {
page: 'scenarios',
details: 'Scenarios',
state: name || 'Running Scenario',
sensitive: false,
}
}

// ── Missions ────────────────────────────────────────────────
if (
pathname.startsWith('/missions')
|| pathname.startsWith('/mission')
) {
const name = extractPageTitle(pathname)
return {
page: 'missions',
details: 'Missions',
state: name || 'On a Mission',
sensitive: false,
}
}

// ── Certifications ──────────────────────────────────────────
if (
pathname.startsWith('/certifications')
|| pathname.startsWith('/certification')
) {
const name = extractPageTitle(pathname)
return {
page: 'certifications',
details: 'Certifications',
state: name || 'Viewing Certifications',
sensitive: false,
}
}

// ── Labs / Machines ─────────────────────────────────────────
if (
pathname.startsWith('/labs')
|| pathname.startsWith('/lab')
|| pathname.startsWith('/machines')
) {
const labName = extractPageTitle(pathname)
return {
page: 'labs',
details: 'Solving Labs',
state: labName || 'Hacking in Progress...',
sensitive: false,
}
}

// ── Support ─────────────────────────────────────────────────
if (pathname.startsWith('/support')) {
return {
page: 'support',
details: 'Support',
state: 'Getting Support',
sensitive: false,
}
}

// ── Learning Paths / Courses ────────────────────────────────
if (
pathname.startsWith('/learning')
|| pathname.startsWith('/paths')
|| pathname.startsWith('/courses')
) {
return {
page: 'learning',
details: 'Learning Paths',
state: 'Studying Cyber Security',
sensitive: false,
}
}

// ── CTF / Challenges ────────────────────────────────────────
if (
pathname.startsWith('/ctf')
|| pathname.startsWith('/challenges')
) {
return {
page: 'ctf',
details: 'CTF Challenge',
state: 'Capturing Flags',
sensitive: false,
}
}

// ── Account Settings ────────────────────────────────────────
if (pathname.startsWith('/account/settings')) {
return {
page: 'settings',
details: 'Settings',
state: 'A few changes',
sensitive: false,
}
}

// ── Pricing Plans ───────────────────────────────────────────
if (pathname.startsWith('/pricing-plans')) {
return {
page: 'pricing',
details: 'Pricing Plans',
state: 'Looking Pricing Plans',
sensitive: false,
}
}

// ── FAQ ─────────────────────────────────────────────────────
if (pathname.startsWith('/frequently-asked-questions')) {
return {
page: 'faq',
details: 'Frequently Asked Questions',
state: 'Looking for answers',
sensitive: false,
}
}

// ── Profile / User ──────────────────────────────────────────
if (
pathname.startsWith('/profile')
|| pathname.startsWith('/user')
|| pathname.startsWith('/settings')
) {
return {
page: 'profile',
details: 'Profile',
state: 'Viewing Profile',
sensitive: false,
}
}

// ── Leaderboard / Rankings ──────────────────────────────────
if (
pathname.startsWith('/leaderboard')
|| pathname.startsWith('/scoreboard')
|| pathname.startsWith('/ranking')
) {
return {
page: 'leaderboard',
details: 'Leaderboard',
state: 'Checking Rankings',
sensitive: false,
}
}

// ── Ticket ──────────────────────────────────────────────────
if (pathname.startsWith('/ticket')) {
return {
page: 'ticket',
details: 'Ticket',
state: 'Viewing Ticket',
sensitive: false,
}
}

// ── Default: browsing ───────────────────────────────────────
return {
page: 'browsing',
details: 'Browsing Platform',
state: '',
sensitive: false,
}
}

// ── Main update loop ────────────────────────────────────────────
presence.on('UpdateData', async () => {
const pathname = document.location.pathname
const pageData = getPageData(pathname)

// Reset timer when the page changes
if (pageData.page !== lastPage) {
startTimestamp = Math.floor(Date.now() / 1000)
lastPage = pageData.page
}

const presenceData: PresenceData = {
startTimestamp,
largeImageKey: 'https://i.ibb.co/ns57qq7g/512x512.jpg',
}

// 265. Satır: ESLint Brace Style Düzeltmesi
if (pageData.sensitive) {
presenceData.details = pageData.details
}
else {
if (pageData.details) {
presenceData.details = pageData.details
}
if (pageData.state) {
presenceData.state = pageData.state
}
}

presence.setActivity(presenceData)
})
Loading