public OpBuddy AddBuddy(string name, byte[] key) { ulong id = Utilities.KeytoID(key); OpBuddy buddy; if (BuddyList.TryGetValue(id, out buddy)) { return(buddy); } buddy = new OpBuddy() { ID = id, Name = name, Key = key }; BuddyList.SafeAdd(id, buddy); Core.IndexName(id, name); // always associate this buddy with name SaveList = true; Core.RunInGuiThread(GuiUpdate); Core.Locations.Research(id); return(buddy); }
public PlanService(OpCore core) { Core = core; Network = core.Network; Protocol = Network.Protocol; Store = Network.Store; Trust = Core.Trust; if (Core.Sim != null) { SaveInterval = 30; } Core.SecondTimerEvent += Core_SecondTimer; Cache = new VersionedCache(Network, ServiceID, DataTypeFile, false); Cache.FileAquired += new FileAquiredHandler(Cache_FileAquired); Cache.FileRemoved += new FileRemovedHandler(Cache_FileRemoved); Cache.Load(); if (!PlanMap.SafeContainsKey(Core.UserID)) { LocalPlan = new OpPlan(new OpVersionedFile(Core.User.Settings.KeyPublic)); LocalPlan.Init(); LocalPlan.Loaded = true; PlanMap.SafeAdd(Core.UserID, LocalPlan); } }
public ChatRoom CreateRoom(string name, RoomKind kind) { ulong id = Utilities.RandUInt64(Core.RndGen); if (kind == RoomKind.Public) { id = ChatService.GetPublicRoomID(name); } ChatRoom room = new ChatRoom(kind, id, name); room.Active = true; room.AddMember(Core.UserID); RoomMap.SafeAdd(id, room); if (kind == RoomKind.Secret) { room.Host = Core.UserID; room.Verified[Core.UserID] = true; SendInviteRequest(room, Core.UserID); // send invite to copies of ourself that exist } Core.RunInGuiThread(Refresh); if (room.PublishRoom) { SetupPublic(room); } return(room); }
public void IndexName(ulong user, string name) { Debug.Assert(name != null && name != ""); if (name == null || name.Trim() == "") { return; } if (NameMap.SafeContainsKey(user)) { return; } NameMap.SafeAdd(user, name); }
private void Cache_FileAquired(OpVersionedFile file) { if (file.UserID != Network.Local.UserID) { return; } // only we can open the buddly list stored on the network byte[] key = Core.User.Settings.KeyPair.Decrypt(file.Header.FileKey, false); using (TaggedStream tagged = new TaggedStream(Cache.GetFilePath(file.Header), Network.Protocol)) using (IVCryptoStream crypto = IVCryptoStream.Load(tagged, key)) { BuddyList.SafeClear(); PacketStream stream = new PacketStream(crypto, Network.Protocol, FileAccess.Read); G2Header root = null; while (stream.ReadPacket(ref root)) { if (root.Name == BuddyPacket.Buddy) { OpBuddy buddy = OpBuddy.Decode(root); ulong id = Utilities.KeytoID(buddy.Key); Core.IndexKey(id, ref buddy.Key); Core.IndexName(id, buddy.Name); if (buddy.Ignored) { IgnoreList.SafeAdd(id, buddy); } else { BuddyList.SafeAdd(id, buddy); } } } } Core.RunInGuiThread(GuiUpdate); }
private IMStatus OpenStatus(ulong user) { IMStatus status; if (!IMMap.SafeTryGetValue(user, out status)) { status = new IMStatus(user); IMMap.SafeAdd(user, status); } return(status); }
public ShareService(OpCore core) { Core = core; Network = core.Network; string rootPath = Core.User.RootPath + Path.DirectorySeparatorChar + "Data" + Path.DirectorySeparatorChar + ServiceID.ToString() + Path.DirectorySeparatorChar; SharePath = rootPath + DataTypeShare.ToString() + Path.DirectorySeparatorChar; Directory.CreateDirectory(SharePath); HeaderPath = SharePath + Utilities.CryptFilename(Core, "ShareHeaders"); PublicPath = rootPath + DataTypePublic.ToString() + Path.DirectorySeparatorChar; Directory.CreateDirectory(PublicPath); DownloadPath = Core.User.RootPath + Path.DirectorySeparatorChar + "Downloads" + Path.DirectorySeparatorChar; Core.SecondTimerEvent += Core_SecondTimer; // data Network.RudpControl.SessionUpdate += new SessionUpdateHandler(Session_Update); Network.RudpControl.SessionData[ServiceID, DataTypeSession] += new SessionDataHandler(Session_Data); Core.Transfers.FileSearch[ServiceID, DataTypeShare] += new FileSearchHandler(Transfers_FileSearch); Core.Transfers.FileRequest[ServiceID, DataTypeShare] += new FileRequestHandler(Transfers_FileRequest); Core.Transfers.FileSearch[ServiceID, DataTypePublic] += new FileSearchHandler(Transfers_PublicSearch); Core.Transfers.FileRequest[ServiceID, DataTypePublic] += new FileRequestHandler(Transfers_PublicRequest); // location TempLocation = new TempCache(Network, ServiceID, DataTypeLocation); Local = new ShareCollection(Core.UserID); Collections.SafeAdd(Core.UserID, Local); LoadHeaders(); }
private void Cache_FileAquired(OpVersionedFile file) { // get profile OpProfile prevProfile = GetProfile(file.UserID); OpProfile newProfile = new OpProfile(file); ProfileMap.SafeAdd(file.UserID, newProfile); if (file.UserID == Core.UserID) { LocalProfile = newProfile; } if ((newProfile == LocalProfile) || (prevProfile != null && prevProfile.Loaded)) { LoadProfile(newProfile.UserID); } // update subs if (Network.Established) { List <LocationData> locations = new List <LocationData>(); Trust.ProjectRoots.LockReading(delegate() { foreach (uint project in Trust.ProjectRoots.Keys) { if (newProfile.UserID == Core.UserID || Trust.IsHigher(newProfile.UserID, project)) { Trust.GetLocsBelow(Core.UserID, project, locations); } } }); Store.PublishDirect(locations, newProfile.UserID, ServiceID, 0, file.SignedHeader); } if (ProfileUpdate != null) { Core.RunInGuiThread(ProfileUpdate, newProfile); } if (Core.NewsWorthy(newProfile.UserID, 0, false)) { Core.MakeNews(ServiceIDs.Profile, "Profile updated by " + Core.GetName(newProfile.UserID), newProfile.UserID, 0, true); } }
private void LoadHeaderFile(string path, OpStorage storage, bool reload, bool working) { try { if (!File.Exists(path)) { return; } bool cached = Network.Routing.InCacheArea(storage.UserID); bool local = false; byte[] key = working ? LocalFileKey : storage.File.Header.FileKey; using (TaggedStream filex = new TaggedStream(path, Network.Protocol)) using (IVCryptoStream crypto = IVCryptoStream.Load(filex, key)) { PacketStream stream = new PacketStream(crypto, Protocol, FileAccess.Read); G2Header header = null; ulong currentUID = 0; while (stream.ReadPacket(ref header)) { if (!working && header.Name == StoragePacket.Root) { StorageRoot packet = StorageRoot.Decode(header); local = Core.UserID == storage.UserID || GetHigherRegion(Core.UserID, packet.ProjectID).Contains(storage.UserID) || Trust.GetDownlinkIDs(Core.UserID, packet.ProjectID, 1).Contains(storage.UserID); } if (header.Name == StoragePacket.File) { StorageFile packet = StorageFile.Decode(header); if (packet == null) { continue; } bool historyFile = true; if (packet.UID != currentUID) { historyFile = false; currentUID = packet.UID; } OpFile file = null; if (!FileMap.SafeTryGetValue(packet.HashID, out file)) { file = new OpFile(packet); FileMap.SafeAdd(packet.HashID, file); } InternalFileMap.SafeAdd(packet.InternalHashID, file); if (!reload) { file.References++; } if (!working) // if one ref is public, then whole file is marked public { file.Working = false; } if (packet.HashID == 0 || packet.InternalHash == null) { Debug.Assert(false); continue; } string filepath = GetFilePath(packet.HashID); file.Downloaded = File.Exists(filepath); if (Loading && file.Downloaded && !ReferencedPaths.Contains(filepath)) { ReferencedPaths.Add(filepath); } if (!file.Downloaded) { // if in local range only store latest if (local && !historyFile) { DownloadFile(storage.UserID, packet); } // if storage is in cache range, download all files else if (Network.Established && cached) { DownloadFile(storage.UserID, packet); } } // on link update, if in local range, get latest files // (handled by location update, when it sees a new version of storage component is available) } } } } catch (Exception ex) { Core.Network.UpdateLog("Storage", "Error loading files " + ex.Message); } }
void Cache_FileAquired(OpVersionedFile file) { // unload old file OpStorage prevStorage = GetStorage(file.UserID); if (prevStorage != null) { string oldPath = GetFilePath(prevStorage); UnloadHeaderFile(oldPath, prevStorage.File.Header.FileKey); } OpStorage newStorage = new OpStorage(file); StorageMap.SafeAdd(file.UserID, newStorage); LoadHeaderFile(GetFilePath(newStorage), newStorage, false, false); // record changes of higher nodes for auto-integration purposes Trust.ProjectRoots.LockReading(delegate() { foreach (uint project in Trust.ProjectRoots.Keys) { List <ulong> inheritIDs = Trust.GetAutoInheritIDs(Core.UserID, project); if (Core.UserID == newStorage.UserID || inheritIDs.Contains(newStorage.UserID)) { // doesnt get called on startup because working not initialized before headers are loaded if (Working.ContainsKey(project)) { bool doSave = Working[project].RefreshHigherChanges(newStorage.UserID); if (!Loading && !SavingLocal) { Working[project].AutoIntegrate(doSave); } } } } }); // update subs - this ensures file not propagated lower until we have it (prevents flood to original poster) if (Network.Established) { List <LocationData> locations = new List <LocationData>(); Trust.ProjectRoots.LockReading(delegate() { foreach (uint project in Trust.ProjectRoots.Keys) { if (newStorage.UserID == Core.UserID || Trust.IsHigher(newStorage.UserID, project)) { Trust.GetLocsBelow(Core.UserID, project, locations); } } }); Store.PublishDirect(locations, newStorage.UserID, ServiceID, FileTypeCache, file.SignedHeader); } if (StorageUpdate != null) { Core.RunInGuiThread(StorageUpdate, newStorage); } if (Core.NewsWorthy(newStorage.UserID, 0, false)) { Core.MakeNews(ServiceIDs.Storage, "File System updated by " + Core.GetName(newStorage.UserID), newStorage.UserID, 0, false); } }
private void CacheFile(SignedData signedHeader, VersionedFileHeader header) { if (Core.InvokeRequired) { Debug.Assert(false); } try { // check if file exists string path = ""; if (header.FileHash != null) { path = GetFilePath(header); if (!File.Exists(path)) { Download(signedHeader, header); return; } } // get file OpVersionedFile prevFile = GetFile(header.KeyID); if (prevFile != null) { if (header.Version < prevFile.Header.Version) { return; // dont update with older version } } OpVersionedFile newFile = new OpVersionedFile(header.Key); // set new header newFile.Header = header; newFile.SignedHeader = signedHeader.Encode(Network.Protocol); newFile.Unique = !Network.Established; FileMap.SafeAdd(header.KeyID, newFile); RunSaveHeaders = true; if (FileAquired != null) { FileAquired.Invoke(newFile); } // delete old file - do after aquired event so invoked (storage) can perform clean up operation if (prevFile != null && prevFile.Header.FileHash != null) { string oldPath = GetFilePath(prevFile.Header); if (path != oldPath && File.Exists(oldPath)) { try { File.Delete(oldPath); } catch { } } } } catch (Exception ex) { Core.Network.UpdateLog("VersionedFile", "Error caching data " + ex.Message); } }
void PumpThread(int index) { while (true) { PumpStart[index].WaitOne(); if (Shutdown) { return; } // send packets foreach (SimPacket packet in InPackets[index]) { switch (packet.Type) { case SimPacketType.Udp: packet.Dest.Core.Sim.BytesRecvd += (ulong)packet.Packet.Length; packet.Dest.UdpControl.OnReceive(packet.Packet, packet.Packet.Length, packet.Source); break; case SimPacketType.TcpConnect: TcpConnect socket = packet.Dest.TcpControl.OnAccept(null, packet.Source); if (socket != null) { TcpSourcetoDest.SafeAdd(packet.Tcp, socket); TcpSourcetoDest.SafeAdd(socket, packet.Tcp); packet.Tcp.OnConnect(); } break; case SimPacketType.Tcp: TcpConnect dest; if (TcpSourcetoDest.SafeTryGetValue(packet.Tcp, out dest)) { dest.Core.Sim.BytesRecvd += (ulong)packet.Packet.Length; packet.Packet.CopyTo(dest.RecvBuffer, dest.RecvBuffSize); dest.OnReceive(packet.Packet.Length); } break; case SimPacketType.TcpClose: TcpConnect destClose; if (TcpSourcetoDest.SafeTryGetValue(packet.Tcp, out destClose)) { destClose.OnReceive(0); TcpSourcetoDest.SafeRemove(packet.Tcp); TcpSourcetoDest.SafeRemove(destClose); } break; } } // send messages from gui if (!TestCoreThread) { Instances.SafeForEach(instance => { if (instance.ThreadIndex != index) { return; } Action <OpCore> runMessages = core => { // process invoked functions, dequeue quickly to continue processing while (core.CoreMessages.Count > 0) { AsyncCoreFunction function = null; lock (core.CoreMessages) function = core.CoreMessages.Dequeue(); if (function != null) { function.Result = function.Method.DynamicInvoke(function.Args); function.Completed = true; function.Processed.Set(); } } }; if (instance.Context.Lookup != null) { runMessages(instance.Context.Lookup); } instance.Context.Cores.SafeForEach(c => runMessages(c)); }); } // instance timer if (CurrentPump == 0) // stepping would cause second timer to run every 250ms without this { Instances.SafeForEach(instance => { if (instance.ThreadIndex == index) { instance.Context.SecondTimer_Tick(null); } }); } PumpEnd[index].Set(); } }
private void Process_LocationData(DataReq data, SignedData signed, LocationData location) { Core.IndexKey(location.UserID, ref location.Key); Debug.Assert(location.UserID == location.Source.UserID); if (location.UserID != location.Source.UserID) { return; } ClientInfo client = GetLocationInfo(location.UserID, location.Source.ClientID); // check location version if (client != null) { if (location.Version == client.Data.Version) { return; } else if (location.Version < client.Data.Version) { if (data != null && data.Source != null) { Network.Store.Send_StoreReq(data.Source, data.LocalProxy, new DataReq(null, client.Data.UserID, ServiceID, 0, client.SignedData)); } return; } } Core.IndexName(location.UserID, location.Name); // notify components of new versions (usually just localsync service signed up for this) DhtAddress address = new DhtAddress(location.IP, location.Source); foreach (PatchTag tag in location.Tags) { if (TagReceived.Contains(tag.Service, tag.DataType)) { TagReceived[tag.Service, tag.DataType].Invoke(address, location.UserID, tag.Tag); } } // add location if (client == null) { // if too many clients, and not us, return if (location.UserID != Core.UserID && ActiveClientCount(location.UserID) > MaxClientsperUser) { return; } client = new ClientInfo(location); Clients.SafeAdd(client.RoutingID, client); // dont need to worry about remote caching old locs indefinitely because if a loc is cached remotely // that means the remote is being continuall pinged, or else the loc would expire // if we're still interested in loc after a min, it will be pinged locally } client.Data = location; client.SignedData = signed.Encode(Network.Protocol); if (client.Data.UserID == Core.UserID && client.Data.Source.ClientID == Network.Local.ClientID) { LocalClient = client; } AddRoutingData(location); // only get down here if loc was new version in first place (recently published) // with live comm trickle down this prevents highers from being direct ping flooded to find their // online status client.LastSeen = Core.TimeNow; SignalUpdate(client, true); }