# Net Kütüphanesi Kullanımı

- **İngilizce aslı:** https://wiki.facepunch.com/gmod/Net_Library_Usage
- **Çeviri tarihi:** 2025-09-08

> **NOT:** Bu sayfayı okumadan önce, lütfen Lua'nın temellerini anladığınızdan emin olun, aksi takdirde takılıp kalırsınız!

## Net Kütüphanesi Nedir?

Net kütüphanesi, istemci ve sunucu arasında veri göndermenin birkaç yolundan biridir.

Net kütüphanesinin en büyük avantajları, usermessage ve konsol komutlarına kıyasla mesaj başına 65533 bayt (yaklaşık 64KiB) gibi büyük bir boyut sınırına sahip olması ve veriyi geriye doğru, yani istemciden sunucuya gönderebilmesidir.

## Net Kütüphanesini Kullanma

### Mesajları Önbelleğe Alma

Bir net mesajı gönderdiğinizde, büyük olasılıkla kısaltılmış bir URL içeren bir hata alırsınız. Bunun nedeni, mesajın önbelleğe alınmamış olmasıdır. Bir mesajı önbelleğe almak için, sunucu tarafında bir kez bunu çağırmanız yeterlidir:

```lua
util.AddNetworkString( "YourMessageName" )
```

> **NOT:** Bu net ismini kullanabilmeniz için bir süre geçmesi gerekir.

### Mesajları Alma

Net kütüphanesi ile veri gönderebilmek için, veri alındığında onu işleyecek bir şey olmalıdır. Bunun için iki argüman alan [net.Receive](https://gmod.tr/wiki/net.Receive) fonksiyonunu kullanırız: net mesajının adı ve mesaj alındığında çalıştırılacak olan geri çağırma (callback) fonksiyonu.

Aşağıda bir net mesajı almanın bir örneği bulunmaktadır:

```lua
net.Receive( "MyMessage", function( len, ply )
    print( "I got it!" )
end )
```

Net mesajımız "MyMessage" gönderildiğinde, alıcı fonksiyon çağrılır. Alıcı fonksiyonun ilk argümanı mesajın uzunluğudur (hata ayıklama veya ağ koruması için kullanılabilir), ikincisi ise onu gönderen oyuncudur; bu yalnızca [net.SendToServer](https://gmod.tr/wiki/net.SendToServer) çağrıldığında kullanılır (bkz. [aşağısı](https://gmod.tr/wiki/Net_Library_Usage#Sending_messages)).

### Mesajları Gönderme

Artık mesajı alacak bir fonksiyonumuz olduğuna göre, mesajı göndermemiz gerekiyor.

Bir net mesajı göndermeden önce, mesajın dize (string) adının sunucu tarafında bir kez [util.AddNetworkString](https://gmod.tr/wiki/util.AddNetworkString) ile önbelleğe alınması gerekir.

```lua
util.AddNetworkString( "myMessage" )
```

Daha sonra bir net mesajı göndermeye başlamak için, mesajın adıyla [net.Start](https://gmod.tr/wiki/net.Start) fonksiyonunu çağırın. Sonra,

- Sunucu tarafı: Tek bir argüman alan [net.Send](https://gmod.tr/wiki/net.Send) fonksiyonunu kullanın: bir [Player](https://gmod.tr/wiki/Player) veya bir oyuncu tablosu. Tüm oyunculara gönderiyorsanız, [net.Broadcast](https://gmod.tr/wiki/net.Broadcast) kullanın.
- İstemci tarafı: [net.SendToServer](https://gmod.tr/wiki/net.SendToServer) kullanın.

Örneğin, myMessage adlı net mesajını sunucudaki ilk oyuncuya göndermek isteseydiniz, şunu yapardınız:

```lua
net.Start( "myMessage" )
net.Send( Entity( 1 ) )
```

Boş bir net mesajı gönderiyoruz, şimdi net mesajlarında veri göndermeye bakacağız. Genellikle boş net mesajları, sunucuda gerçekleşen ve sunucu onlara bildirmedikçe istemcinin haberdar olmadığı bir şeyi oyuncuya bildirmenin basit bir yolu olarak kullanılır. Örneğin, sunucuda belirli bir süre geçtikten sonra, istemciye bir menünün açılması gerektiğini bildirmek için boş bir net mesajı gönderilebilir.

### Veri Aktarımı

Veri göndermek için, [net.Start](https://gmod.tr/wiki/net.Start) fonksiyonunu çağırdıktan sonra, her biri kendi veri türü için olan aşağıdaki fonksiyonları kullanabilirsiniz:

- [net.WriteBool](https://gmod.tr/wiki/net.WriteBool)
- [net.WriteString](https://gmod.tr/wiki/net.WriteString)
- [net.WriteInt](https://gmod.tr/wiki/net.WriteInt)
- [net.WriteUInt](https://gmod.tr/wiki/net.WriteUInt)
- [net.WriteFloat](https://gmod.tr/wiki/net.WriteFloat)
- [net.WriteDouble](https://gmod.tr/wiki/net.WriteDouble)
- [net.WriteAngle](https://gmod.tr/wiki/net.WriteAngle)
- [net.WriteVector](https://gmod.tr/wiki/net.WriteVector)
- [net.WriteNormal](https://gmod.tr/wiki/net.WriteNormal)
- [net.WriteColor](https://gmod.tr/wiki/net.WriteColor)
- [net.WriteTable](https://gmod.tr/wiki/net.WriteTable)
- [net.WriteEntity](https://gmod.tr/wiki/net.WriteEntity)
- [net.WriteData](https://gmod.tr/wiki/net.WriteData)
- [net.WriteBit](https://gmod.tr/wiki/net.WriteBit)
- [net.WriteType](https://gmod.tr/wiki/net.WriteType)

Mesajı göndermek için sunucuda [net.Send](https://gmod.tr/wiki/net.Send), istemcide ise [net.SendToServer](https://gmod.tr/wiki/net.SendToServer) kullanın. Ayrıca sunucu tarafında [net.Broadcast](https://gmod.tr/wiki/net.Broadcast) kullanarak bağlı olan her oyuncuya bir mesaj gönderebilirsiniz.

Veri okumak için, yukarıdaki her yazılabilir veri türü için genellikle net.Read(Tür) şeklinde fonksiyonlar mevcuttur.

> **NOT:** Veriyi gönderdiğiniz sırayla okumanız gerekir.

### Örnekler

Bunları denemeden önce hook'lar hakkında temel bir anlayışa sahip olmanız önerilir.

#### Örnek 1: İstemciye bir oyuncunun öldüğünü bildirme.

[GM:PlayerDeath](https://gmod.tr/wiki/GM:PlayerDeath), yalnızca sunucu tarafında çağrılan bir hook'tur. Her oyuncuya bir oyuncunun öldüğünü bildirmek istersek, net kütüphanesini kullanabiliriz.

Sunucu tarafı:

```lua
util.AddNetworkString( "PlayerDied" )

hook.Add( "PlayerDeath", "NotifyClient", function( ply, inf, att )
        net.Start( "PlayerDied" )
        net.WriteEntity( ply )
        net.Broadcast()
end )
```

İstemci tarafı:

```lua
net.Receive( "PlayerDied", function()
    local ply = net.ReadEntity()
    if not ply:IsValid() then return end -- Make sure the dead player exists
    chat.AddText( ply, Color( 255, 0, 0 ), " öldü!" )
end )
```

Açıklama:

chat.AddText, yalnızca istemcide kullanabileceğimiz bir fonksiyon olduğundan, istemciye bir oyuncunun öldüğünü bildirmenin bir yolunu bulmamız gerekiyor. Çözüm basit, [GM:PlayerDeath](https://gmod.tr/wiki/GM:PlayerDeath) hook'unda, entity'yi istemciye göndermek için [net.WriteEntity](https://gmod.tr/wiki/net.WriteEntity) kullanın, entity'yi okuyun ve ardından istediğimiz renklerle chat.AddText'i çalıştırın.

Meydan Okumalar (Bunları yapmadan ilerlemeyin!):

- Herkesin, oyuncunun kim tarafından öldürüldüğünü görmesini sağlayabilir misiniz?
- Sadece saldıran oyuncuya bir oyuncu öldürdüğünü bildirecek şekilde düzenleyebilir misiniz?

#### Örnek 2: İstemciden sunucuya bilgi verme.

Oyuncunun kaç yaşında olduğunu bilmek istiyoruz ve aynı zamanda sunucudaki herkesin bunu bilmesini istiyoruz. Sorun şu ki, VGUI fonksiyonları yalnızca istemci tarafında çağrılabilir, ama endişelenmeyin, net kütüphanesi burada!

İstemci tarafı:

```lua
local frame = vgui.Create( "DFrame" )
frame:SetSize( 400, 400 )
frame:SetTitle( "Yaşınız kaç?" )
frame:Center()

local age = vgui.Create( "DNumberWang", frame )
age:Dock( TOP )
age:SetDecimals( 0 )
age:SetMin( 0 )
age:SetMax( 100 )

local send = vgui.Create( "DButton", frame )
send:Dock( TOP )
send:SetText( "Yaşımı gönder!" )
send.DoClick = function()
    net.Start( "SendAge" )
    net.WriteUInt( age:GetValue(), 8 ) -- İkinci argüman 8'dir, çünkü yaş asla 255'in üzerinde olmayacaktır. Bunu yapmak bant genişliğinden tasarruf sağlar ve bant genişliğini azaltabilir.
    net.SendToServer()
end
```

[net.WriteEntity](https://gmod.tr/wiki/net.WriteEntity) kullanarak sunucuya kim olduğumuzu bildirmediğimize dikkat edin. Bunun nedeni, sunucu tarafında [net.Receive](https://gmod.tr/wiki/net.Receive)'ın ikinci argümanının mesajı gönderen oyuncu olmasıdır. Bu örnekten sonra net mesajı güvenliği hakkında daha derine ineceğiz.

Sunucu tarafı:

```lua
util.AddNetworkString( "SendAge" )

net.Receive( "SendAge", function( len, ply ) -- len, net mesajının uzunluğudur ki bunu umursamıyoruz, ply ise mesajı gönderen oyuncudur.
    local age = net.ReadUInt( 8 ) -- ReadUInt'ın bir argüman gerektirdiğine dikkat edin. Bu, WriteUInt'ın ikinci argümanıdır ve bize sayının ne kadar büyük olduğunu söyler.
    PrintMessage( HUD_PRINTTALK, ply:Nick() .. " " .. age .. " yaşında!" )
 end )
```

Meydan Okumalar (Bunları yapmadan devam etmeyin!): Yaş mesajının renkli görünmesini sağlayabilir misiniz? Mesajın aynı zamanda oyuncunun en sevdiği yemeği de göstermesini sağlayabilir misiniz?

### Güvenlik

İstemciden sunucuya bir net mesajı gönderirken, büyük bir güvenlik riski oluşturursunuz. Bir anlığına birinin sunucu tarafında şu kodu yazdığını farz edelim:

```lua
util.AddNetworkString( "BanPlayer" )

net.Receive( "BanPlayer", function( len, ply )
    local toBan = net.ReadEntity()
    local time = net.ReadUInt( 32 )
    toBan:Ban( time, true )
end )
```

Bu koda bir göz atın. Bu kod gerçekten bir sunucuda kullanılsaydı ne olabileceğini anlayabiliyor musunuz?

Hadi parçalara ayıralım. Bu net mesajı, BanPlayer net mesajı sunucuya gönderildiğinde bir oyuncuyu yasaklar. Ancak, oyuncunun gerçekten bir admin olup olmadığını kontrol eden hiçbir denetim yoktur. Bu, insanların kendi net mesajlarını, oluşturulduğu betiğin dışından göndererek sunucunuzdaki herhangi bir oyuncuyu yasaklama erişimi kazanabileceği anlamına gelir. Bunu önlemek için 1 basit kuralı izleyin:

**İSTEMCİYE GÜVENMEYİN**

Kullanıcı girdisi üzerindeki kontrolleri istemci tarafında yapıp sonra sunucu tarafında bunların sorunsuz olduğunu varsaymayın. Tembel olmayın ve veriyi sadece kolayca manipüle edilebildiği alanda kontrol etmeyin. Negatif sayılara, çok hızlı net mesajı gönderenlere, asla yazılmaması gereken entity'leri yazmaya çalışanlara ve daha birçok şeye karşı dikkatli olmalısınız. Kodunuzu yayınlamadan önce, onu kırmak için elinizden gelenin en iyisini yapın. Kullanıcıdan girdi istemeye devam edebilirsiniz, endişe bu girdinin geçerliliğindedir.

> **UYARI:** Bu, mesajı kimin gönderdiğini bilmek istediğinizde ve net.Receive'daki ikinci argümanı kullanmak yerine istemci tarafında `net.WriteEntity(LocalPlayer())` ve sunucu tarafında `local caller = net.ReadEntity()` yaptığınızda sık karşılaşılan bir sorundur. Bunu yapmayın, bu sunucu kodunuzu açığa çıkarır ve istismar edilebilir!

Net fonksiyonlarınızı güvence altına almanın kolay bir yolu:

```lua
net.Receive("YourNetName", function( len, ply )
    if !ply:IsSuperAdmin() then return end -- gönderen superadmin değilse fonksiyondan çıkar
    print( "This is a secured Net Message!" )
end)
```

## İyileştirme

> **NOT:** Bu bölüm, karmaşıklığı nedeniyle yeni başlayanlar için önerilmez.

Net iletişiminizi tasarlarken, onu olabildiğince etkili hale getirmek önemlidir.

İşte kontrol edebileceğiniz bazı bölümler:

### Basitleştirme

Aynı verimlilikle ne kadar az veri gönderebilirseniz o kadar iyidir.

#### Her iki taraf için de zaten bilinebilecek verileri bulun.

[Player:SendLua](https://gmod.tr/wiki/Player:SendLua) ve [BroadcastLua](https://gmod.tr/wiki/Global.BroadcastLua) kullanmaktan kaçınmaya çalışın.

Her seferinde tüm derma menüsünü istemciye göndermenize gerek yok. Bu menüyü açan bir istemci taraflı fonksiyon oluşturun ve sunucu tarafından boş bir net mesajı gönderin.

Önceki net maliyeti: mesaj başına `(kodun uzunluğu + 1) * 8` bit.

Sonraki net maliyeti: mesaj başına `0` bit.

#### Int ve UInt'ler için uygun bit miktarını bulun

Yeni başlayan biri olarak [net.WriteUInt](https://gmod.tr/wiki/net.WriteUInt) ve [net.WriteInt](https://gmod.tr/wiki/net.WriteInt)'in ikinci parametresinde 32 bit kullanmanıza izin verilir, ancak küçük sayılar gönderiyorsanız bu çok fazladır. [net.WriteUInt](https://gmod.tr/wiki/net.WriteUInt) ve [net.WriteInt](https://gmod.tr/wiki/net.WriteInt) sayfalarında ihtiyacınız olan bit miktarını bulmak için kullanabileceğiniz tablolar bulunur.

Örneğin oyuncu seçtiği bir sayıyı gönderir, sayının 0 ile 64 arasında olması gerektiğini bilirsiniz. Bu sayı, etkilenecek oyuncu miktarını temsil eder (sunucuda 64 yuva vardır). Negatif değerlerimiz yok, bu yüzden [net.WriteUInt](https://gmod.tr/wiki/net.WriteUInt) kullanıyoruz. 65 sayıyı (0-64) sığdırmak için 7 bite ihtiyacımız var.

7 bit kesinlikle 32'den daha iyidir, ancak burada mantığımızı kullanabiliriz: eğer bu bir oyuncu tarafından gönderiliyorsa, en az bir oyuncu var demektir, bu yüzden `0` olamaz, oyuncunun 1'den 64'e kadar seçim yapmasını sağlayabiliriz. Bu hala 7 bit, ancak gönderirken 1 çıkarıp (ve okurken 1 ekleyerek) 6 bit ile yapabiliriz.

```lua
send.DoClick = function()
	net.Start( "SelectPlayers" )
	net.WriteUInt( slider:GetValue() - 1, 6 )
	net.SendToServer()
end
```

```lua
net.Receive( "SelectPlayers", function()
	local amount = net.ReadUInt(6) + 1
	print( "Amount:", amount )
end )
```

Önceki net maliyeti: mesaj başına `32` bit.

Sonraki net maliyeti: mesaj başına `6` bit.

#### net.WriteTable yerine statik bir yapı göndermeyi deneyin

[net.WriteTable](https://gmod.tr/wiki/net.WriteTable) çok başlangıç dostu bir fonksiyondur ancak aşırı maliyetlidir. Diyelim ki sunucuya bir [SunInfo yapısı](https://gmod.tr/wiki/Structures/SunInfo) göndermek istiyorsunuz. Bu yapının 2 alanı vardır: bir vektör ve bir sayı.

[net.WriteTable](https://gmod.tr/wiki/net.WriteTable)'ın sorunu, sayınızın ne kadar büyük olabileceğini bilmemesidir, vektörleri normalleştirilmiş vektörlerden ayırmaz. [net.WriteTable](https://gmod.tr/wiki/net.WriteTable) anahtar türünü, anahtar verisini, değer türünü, değer verisini gönderir. Türü yazmak 8 bit maliyetlidir. Vektör maliyetleri değişken bit miktarıdır. [net.WriteTable](https://gmod.tr/wiki/net.WriteTable) tüm sayıları 64 bit olan double olarak yazar. [net.WriteTable](https://gmod.tr/wiki/net.WriteTable) tüm vektörleri (normalleştirilmiş ve değil) vektör olarak yazar.

Yani [SunInfo yapısını](https://gmod.tr/wiki/Structures/SunInfo) [net.WriteTable](https://gmod.tr/wiki/net.WriteTable) ile gönderirseniz şunu gönderecektir:

```lua
net.WriteTable( util.GetSunInfo() )
```

| Yazılan Bit | Değer Türü | Değer | Açıklama |
|---|---|---|---|
| 8 | `number` | `TYPE_STRING` | Anahtar türü (UInt) |
| 80 | `string` | `direction` | Anahtar |
| 8 | `number` | `TYPE_VECTOR` | Değer türü (UInt) |
| 3-69 | `Vector` | `util.GetSunInfo().direction` | Değer |
| 8 | `number` | `TYPE_STRING` | Anahtar türü (UInt) |
| 96 | `string` | `obstruction` | Anahtar |
| 8 | `number` | `TYPE_NUMBER` | Değer türü (UInt) |
| 64 | `number` | `util.GetSunInfo().obstruction` | Değer |
| 8 | `number` | `TYPE_NIL` | Tablonun sonu |

Toplam: **mesaj başına minimum 283 bit. mesaj başına maksimum ~349 bit**.

Bu çok maliyetlidir, tablodaki alanlarımızı bildiğimiz için anahtarlardan kurtulabiliriz (283-349'dan 91-157'ye).

Ayrıca değerlerimizi de biliyoruz, bu yüzden türlerini göndermemize gerek yok.

Bu noktada [net.WriteTable](https://gmod.tr/wiki/net.WriteTable) kullanmayı bırakmalısınız.

Normalleştirilmiş vektör için [net.WriteNormal](https://gmod.tr/wiki/net.WriteNormal) (daha az bit maliyeti ve çok fazla hassasiyet kaybı olmaz) ve normalleştirilmiş sayı için [net.WriteFloat](https://gmod.tr/wiki/net.WriteFloat) kullanalım (tam hassasiyet gerekiyorsa [net.WriteDouble](https://gmod.tr/wiki/net.WriteDouble) kullanın, ama burada o kadar önemli değil):

```lua
local suninfo = util.GetSunInfo()
net.WriteNormal( suninfo.direction )
net.WriteFloat( suninfo.obstruction )
```

| Yazılan Bit | Değer Türü | Değer |
|---|---|---|
| 3-27 | `Vector` | `suninfo.direction` |
| 32 | `number` | `suninfo.obstruction` |

Toplam: mesaj başına minimum 35 bit. mesaj başına maksimum 59 bit.

Bence fark oldukça açık.

#### Sıkıştırma

Büyük miktarda veri göndermeniz gerekiyorsa, onu sıkıştırabilirsiniz.

Bu yöntem net bant genişliğinden tasarruf sağlar ancak CPU süresini artırabilir.

> **UYARI:** Bu yöntem, istemciden sunucuya iletişim için kullanıldığında hash-DOS (hash çarpışması hizmet reddi) saldırısı riski nedeniyle JSON için önerilmez.

Sıkıştırma için kullanılan fonksiyonlar şunlardır: [util.Compress](https://gmod.tr/wiki/util.Compress), [util.Decompress](https://gmod.tr/wiki/util.Decompress), [net.WriteData](https://gmod.tr/wiki/net.WriteData), [net.ReadData](https://gmod.tr/wiki/net.ReadData), [net.WriteUInt](https://gmod.tr/wiki/net.WriteUInt) ve [net.ReadUInt](https://gmod.tr/wiki/net.ReadUInt).

Gönderme:

```lua
local compressedString = util.Compress( largestring )
local len = #compressedString
net.WriteUInt( len, 16 )
net.WriteData( compressedString, len )
```

Önce dizeyi sıkıştırmamız ve [net.WriteData](https://gmod.tr/wiki/net.WriteData) ile göndermemiz gerekir. Ancak [net.ReadData](https://gmod.tr/wiki/net.ReadData) uzunluğu gerektirir, bu yüzden önce onu ve sonra verinin kendisini göndermemiz gerekir.

Okuma:

```lua
local len = net.ReadUInt( 16 )
local compressedString = net.ReadData( len )
local largestring = util.Decompress( compressedString )
```

Önce sıkıştırılmış dizenin uzunluğunu almalı, sonra onu okuyup sıkıştırmayı açmalıyız.

> **NOT:** Eğer net mesajınız yalnızca sıkıştırılmış bir dize içeriyorsa, [net.Receive](https://gmod.tr/wiki/net.Receive)'dan gelen bir `len` argümanını kullanabilir ve `local len = net.ReadUInt( 16 )` yerine onu kullanabilirsiniz.

### Dengeleme

Çok fazla mesaj veya çok fazla veri gönderilirse net kanalı taşabilir. Bunun için yapılabilecekler şunlardır:

#### Net mesajlarınız için en uygun oranı bulun

Net mesajlarının zamanı ve boyutu arasında bir denge bulabilirsiniz.

Eğer gecikme (lag) yaşadıysanız, anında göndermeniz gerekmiyorsa, muhtemelen net mesajını parçalara ayırmalısınız.

Mesajları göndermek için en uygun gecikmeyi bulun. Onları saniyede bir yerine dakikada bir gönderebilir misiniz?

#### Sıkıştırma

Büyük veri göndermeniz gerekiyorsa ve onu geciktiremiyor veya bölemiyorsanız, [yukarıda bahsedilen](https://gmod.tr/wiki/Net_Library_Usage#compression) sıkıştırma yöntemini kullanın.

#### Güvenilmez mod (Unreliable mode)

[net.Start](https://gmod.tr/wiki/net.Start)'ın ikinci bir parametresi vardır: `unreliable`. Bu, mesajı bir ağ paketindeki “güvenilmez” katman üzerinden gönderilecek şekilde ayarlar.

Adının akla getirebileceğinin aksine, bu, net mesajının kaybolabileceği veya bozulabileceği anlamına gelmez; hala TCP onaylı bir paket üzerinde ilerlemektedir.

Çok büyük olan güvenilir (reliable) net mesajları, ağ arabelleğinin taşmasına neden olarak istemcinin bağlantısını keser. “Overflowed reliable channel” hatası bu anlama gelir.

Buna karşı koymak için net mesajlarınızda güvenilmez modu ayarlayabilirsiniz. Güvenilmez mesajlar, güvenilir katmana eklenir. Bir istemci, güvenilmez veriler içeren büyük bir paket aldığında, güvenilmez veriler önce atılır ve oyun onsuz devam eder.

Bu, net mesajlarınızın taşmasını önlemeye yardımcı olmalıdır, ancak istemciye ulaşmaları garanti değildir. Bu, kaybolması durumunda hiçbir şeyi bozmayacak bilgileri göndermek için kullanılabilir.

Unutmayın: tüm net mesajlarının güvenilmez olması gerekmez. Bunu yapsaydınız, hepsi “ya hep ya hiç” şeklinde bırakılır ve istemci hiç veri almazdı. Verinin ortasında bir kesilme olmaz; güvenilir/güvenilmez ayrımı, alınan veri için tek ayırıcıdır.

- [GMod Wiki ana sayfası](https://gmod.tr/wiki)

---

[Tüm sunucular](https://gmod.tr/) · [GmodTR Launcher](https://gmod.tr/launcher) · [Rehber](https://gmod.tr/rehber) · [GMod Wiki](https://gmod.tr/wiki) · [GmodTR nedir?](https://gmod.tr/hakkinda) · [Sunucu ekle](https://gmod.tr/sunucu-ekle) · [Discord](https://discord.gg/gmodtr)

Kaynak: https://gmod.tr/wiki/Net_Library_Usage
